Community
Participate
Working Groups
Build Identifier: M20100909-0800 When a backspace character or form feed character is used in an mtl file, it fails when it tries to export to xml to produce the emtl file. This can be triggered in at least two ways and I have not found any temporary work around (which I am desperate to find). This bug appears to have been also found in another project (XText): bug 327080. Reproducible: Always Steps to Reproduce: In the following two examples: [query s1(input : String) : String = 'VALUE1' /] [template public s2(s : String)]VALUE2[/template] * Where VALUE1 is a backslash "\" followed by one of the following: "b" (backspace), "f" (form feed), or anything in the range "000".."037" except for "011" (tab), "012" (linefeed) and "015" (carriage return). * Where VALUE1 or VALUE2 is one of the unescaped values of these characters (for example, copy-pasting the backspace character into the document). The error looks as follows: Errors occurred during the build. Errors running builder 'Acceleo Builder' on project 'myproject'. java.lang.RuntimeException: An invalid XML character (Unicode: 0x8) was found in the element content: at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl$Escape.convert(XMLSaveImpl.java:3298) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.getDatatypeValue(XMLSaveImpl.java:3082) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveDataTypeSingle(XMLSaveImpl.java:1678) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveFeatures(XMLSaveImpl.java:1265) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElementID(XMLSaveImpl.java:2685) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElement(XMLSaveImpl.java:1174) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElement(XMLSaveImpl.java:1035) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveContainedSingle(XMLSaveImpl.java:2372) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveFeatures(XMLSaveImpl.java:1527) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElementID(XMLSaveImpl.java:2685) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElement(XMLSaveImpl.java:1174) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElement(XMLSaveImpl.java:1035) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveContainedMany(XMLSaveImpl.java:2386) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveFeatures(XMLSaveImpl.java:1533) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElementID(XMLSaveImpl.java:2685) at org.eclipse.emf.ecore.xmi.impl.XMISaveImpl.writeTopObjects(XMISaveImpl.java:90) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.traverse(XMLSaveImpl.java:592) at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.save(XMLSaveImpl.java:256) at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doSave(XMLResourceImpl.java:206) at org.eclipse.acceleo.model.mtl.resource.EMtlResourceImpl.doSave(EMtlResourceImpl.java:88) at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1406) at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:993) at org.eclipse.acceleo.parser.AcceleoParser.parse(AcceleoParser.java:216) at org.eclipse.acceleo.parser.AcceleoParser.parse(AcceleoParser.java:87) at org.eclipse.acceleo.internal.ide.ui.builders.AcceleoCompileOperation.doCompileResources(AcceleoCompileOperation.java:170) at org.eclipse.acceleo.internal.ide.ui.builders.AcceleoCompileOperation.run(AcceleoCompileOperation.java:126) at org.eclipse.acceleo.internal.ide.ui.builders.AcceleoBuilder.incrementalBuild(AcceleoBuilder.java:243) at org.eclipse.acceleo.internal.ide.ui.builders.AcceleoBuilder.build(AcceleoBuilder.java:94) at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:629) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:172) at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:203) at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:255) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:258) at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:311) at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:343) at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:144) at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:242) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
*** Bug 308674 has been marked as a duplicate of this bug. ***
I notice in bug 308674 you wrote "It does block serialization of the emtl file, but isn't a priority." Is that because you know of some way, any way, to get one of these characters into a target document? Even if there was a function like char(0), that would be helpful. The only idea I have is to specify a java function to be called from the mtl file to output these characters, but talk about overkill.
Michel, It "is not a priority" since it isn't something that we see every day in Acceleo templates, and it will be hard to fix. As for workarounds ... Something like this should allow you to output such characters : ['\\n'] or ['\\']['n']
(In reply to comment #3) > Michel, > > It "is not a priority" since it isn't something that we see every day in > Acceleo templates, and it will be hard to fix. As for workarounds ... Something > like this should allow you to output such characters : > > ['\\n'] or ['\\']['n'] You mean ['\\n'/], right? Or ['\\'/]['n'/]? That seems to only output a backslash character followed by an n character, and not a newline (also, even if it did, there is no difficulty representing these three characters despite being <32 aka <040: \r, \n or \t).
Hi Michel, > > ['\\n'] or ['\\']['n'] > > You mean ['\\n'/], right? Or ['\\'/]['n'/]? Yup, forgot the trailing /. "\\n" is indeed meant to output a backslash followed by "n". If what you wish to output is a new line, remove one of the two backslashes : ['\n'/]
I think you're missing the whole point of the bug. This works fine for a \n, \r and \t, but try to do ['\b' /]. You'll get the error described.
Michel, As hinted in comment c3 ... it "should" allow you to :p. I know I have seen this before (thus bug 308674), yet I was not sure about any workaround. if ['\b'/] doesn't work ... then I have no workaround to propose. I stopped investigating bug 308674 when I saw that the actual issue lied in the serialization of the XML. I don't know if it is an issue with OCL, EMF or the XML serializer underneath, but I do know that it ends up serializing the "\b" string instead of the corresponding XML entity (), and that causes the deserialization to fail. As mentionned earlier, this isn't a priority for us because of the fix complexity versus bug frequence ratio. If it _is_ a priority for you, you can either try and fix this yourself (we'll always welcome patches) or buy commercial support from either Obeo (http://obeo.fr/pages/maintenance-and-support/en) or any other company that would propose maintenance support for Acceleo.
Laurent, I know Acceleo is young (particularly with its support of the OMG spec), so you probably have a lot on your plate that you would like to accomplish such that many things have priority. I sympathize with that. I just want to focus on something: Acceleo, without any work-around to speak of, makes it absolutely impossible to generate these characters. Isn't this something that should worry you? A number of output formats, you simply cannot support, which would make me think twice if I were to use Acceleo in my company's core tool set. There are a lot of ways to make support possible without a high cost. Why not add escape and unescape functions to your set of custom functions? That way I could do something like model.value.startsWith('\\b'.unescape()) or model.value.escape().startsWith('\\b'). In other words, there is a difference between "inability to convert certain escaped literal characters", which is only an inconvenience if there is no work-around, and "inability to generate certain characters", which makes a whole set of output formats unavailable to you. If you are interested in the escape and unescape functions, I can look into what kind of effort is required to add a function to your core set. Otherwise, as I am currently in a situation with a fast-approaching deadline, I'll only be able to help out at the later end of 2011, and in the meantime I'll code a java function to do the work temporarily. I don't know about helping out with the underlying problem of how stuff is encoded, as I personally just need something that works, not something that works effortlessly (so escape and unescape would be my preference). I'll give the encoding of these troublesome characters a look, but I suspect it would require a lot of effort, and not only because of the code involved, but also... I found a solution in another project that had this problem with encoding backspace characters. They decided to go with encoding all string literals in base64. If I decided to do that, would I get significant resistance to that because you would want to support emtl file format backwards compatibility? Anyway, I'll look into all this and report back if there are any new developments. Thanks for your quick responses.
Michel, If you simply need a quick workaround, you should probably try to output these characters through Java services. I haven't tried myself, so I can't confirm it will work, but Acceleo calls the Java service and simply outputs the String it returns, so I believe special characters would also be returned as is. Something like : public class MyService { public String getBackslash() { return "\b"; } } and in your template : [query public getBackslash() : String = invoke('my.package.MyService', 'getBackslash()', Sequence{})/]
Sorry for not being clear. That's what I meant when I wrote "in the meantime I'll code a java function to do the work temporarily". Thanks.
This is due to the XMI serialization of the compiled files and there are no plans to fix this