Home » Modeling » M2T (model-to-text transformation) » [Acceleo] Invalid attributes during template invocation
[Acceleo] Invalid attributes during template invocation [message #975044] |
Wed, 07 November 2012 09:52  |
Eclipse User |
|
|
|
Hi,
I am using Eclipse 3.6.2, EMF 2.6.1 and Acceleo 3.3.1.v20120912 on Linux.
I have defined the following metamodels
MM1
Class A
Attr1 : String
Attr2 : String
MM2
Class B extends A
Attr3 : String (derived from Attr1 and Attr2)
MM3
Class C extends B
*** more attributes***
Class D extends B
*** more attributes***
I should probably mention that MM1 lives in a plugin installed in my Eclipse while MM2 and MM3 containing plugins live in my workspace.
Now, I have written a simple Acceleo template which iterates over C instances
[template public AcceleoMain(anInstance: C)]
[comment @main /]
[file ('stdout', false, 'UTF-8')]
Generating [anInstance.Attr3 /] from [anInstance.Attr1 /] and [anInstance.Attr2 /]
[/file]
[/template]
This template is successfully compiled by Acceleo. Yet, I am running into trouble when launching the generation
!ENTRY org.eclipse.ocl 4 10 2012-11-07 15:26:57.015
!MESSAGE Evaluation failed with an exception: (no message)
!STACK 0
java.lang.IllegalArgumentException
at org.eclipse.ocl.ecore.EcoreEvaluationEnvironment.navigateProperty(EcoreEvaluationEnvironment.java:226)
at org.eclipse.ocl.ecore.EcoreEvaluationEnvironment.navigateProperty(EcoreEvaluationEnvironment.java:1)
at org.eclipse.ocl.EvaluationVisitorImpl.visitPropertyCallExp(EvaluationVisitorImpl.java:1925)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitPropertyCallExp(AcceleoEvaluationVisitor.java:1239)
at org.eclipse.ocl.ecore.impl.PropertyCallExpImpl.accept(PropertyCallExpImpl.java:238)
at org.eclipse.ocl.AbstractEvaluationVisitor.visitExpression(AbstractEvaluationVisitor.java:247)
at org.eclipse.ocl.EvaluationVisitorDecorator.visitExpression(EvaluationVisitorDecorator.java:156)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1887)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1042)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoFileBlock(AcceleoEvaluationVisitor.java:423)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1848)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1042)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoForBlock(AcceleoEvaluationVisitor.java:536)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1835)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1042)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoTemplate(AcceleoEvaluationVisitor.java:914)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1819)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1042)
at org.eclipse.ocl.internal.evaluation.QueryImpl.evaluate(QueryImpl.java:152)
at org.eclipse.ocl.ecore.QueryImpl.evaluate(QueryImpl.java:62)
at org.eclipse.acceleo.engine.generation.AcceleoEngine.doEvaluate(AcceleoEngine.java:365)
at org.eclipse.acceleo.engine.generation.AcceleoEngine.evaluate(AcceleoEngine.java:142)
at org.eclipse.acceleo.engine.service.AcceleoService.doGenerateTemplate(AcceleoService.java:884)
at org.eclipse.acceleo.engine.service.AcceleoService.doGenerate(AcceleoService.java:575)
at org.eclipse.acceleo.engine.service.AbstractAcceleoGenerator.generate(AbstractAcceleoGenerator.java:193)
at org.eclipse.acceleo.engine.service.AbstractAcceleoGenerator.doGenerate(AbstractAcceleoGenerator.java:158)
...
On stdout, I get the following values:
Attr3: Correct value, as derived from Attr1 and Attr2
Attr1/2: org.eclipse.emf.ecore.impl.DynamicEObjectImpl@27979138 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@4fbf07d6 (name: OclInvalid_Class) (instanceClassName: null) (abstract: false, interface: false))
It looks like that Acceleo cannot access Attr1 and Attr2 fields at runtime, but I have no idea why. Before Acceleo activation, I checked in the Debugger that all three attributes were correctly set for all C instances.
Worse, I do not face these issues with the generator that operates on D instances.
Were should I start investigating ?
Thanks,
Michaël
|
|
|
Re: [Acceleo] Invalid attributes during template invocation [message #975392 is a reply to message #975044] |
Wed, 07 November 2012 15:56   |
Eclipse User |
|
|
|
Hi
Acceleo's messages are not always perfect. I suspect that navigation
from null has yielded invalid.
If you do a Debug launch as a Java application you can examine the stack
context of the PropertyCallExpImpl.accept and work out what navigation
is probably failing.
Regards
Ed Willink
On 07/11/2012 14:52, Michaël Melchiore wrote:
> Hi,
>
> I am using Eclipse 3.6.2, EMF 2.6.1 and Acceleo 3.3.1.v20120912 on Linux.
>
> I have defined the following metamodels
>
> MM1
> Class A
> Attr1 : String
> Attr2 : String
>
> MM2
> Class B extends A
> Attr3 : String (derived from Attr1 and Attr2)
>
> MM3
> Class C extends B
> *** more attributes***
> Class D extends B
> *** more attributes***
>
> I should probably mention that MM1 lives in a plugin installed in my
> Eclipse while MM2 and MM3 containing plugins live in my workspace.
>
> Now, I have written a simple Acceleo template which iterates over C
> instances
>
> [template public AcceleoMain(anInstance: C)]
> [comment @main /]
> [file ('stdout', false, 'UTF-8')]
> Generating [anInstance.Attr3 /] from [anInstance.Attr1 /] and
> [anInstance.Attr2 /]
> [/file]
> [/template]
>
> This template is successfully compiled by Acceleo. Yet, I am running
> into trouble when launching the generation
>
> !ENTRY org.eclipse.ocl 4 10 2012-11-07 15:26:57.015
> !MESSAGE Evaluation failed with an exception: (no message)
> !STACK 0
> java.lang.IllegalArgumentException
> at
> org.eclipse.ocl.ecore.EcoreEvaluationEnvironment.navigateProperty(EcoreEvaluationEnvironment.java:226)
> at
> org.eclipse.ocl.ecore.EcoreEvaluationEnvironment.navigateProperty(EcoreEvaluationEnvironment.java:1)
> at
> org.eclipse.ocl.EvaluationVisitorImpl.visitPropertyCallExp(EvaluationVisitorImpl.java:1925)
> at
> org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitPropertyCallExp(AcceleoEvaluationVisitor.java:1239)
> at
> org.eclipse.ocl.ecore.impl.PropertyCallExpImpl.accept(PropertyCallExpImpl.java:238)
> at
> org.eclipse.ocl.AbstractEvaluationVisitor.visitExpression(AbstractEvaluationVisitor.java:247)
> at
> org.eclipse.ocl.EvaluationVisitorDecorator.visitExpression(EvaluationVisitorDecorator.java:156)
> at
> org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1887)
> at
> org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1042)
> at
> org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoFileBlock(AcceleoEvaluationVisitor.java:423)
> at
> org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1848)
> at
> org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1042)
> at
> org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoForBlock(AcceleoEvaluationVisitor.java:536)
> at
> org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1835)
> at
> org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1042)
> at
> org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoTemplate(AcceleoEvaluationVisitor.java:914)
> at
> org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1819)
> at
> org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1042)
> at
> org.eclipse.ocl.internal.evaluation.QueryImpl.evaluate(QueryImpl.java:152)
> at org.eclipse.ocl.ecore.QueryImpl.evaluate(QueryImpl.java:62)
> at
> org.eclipse.acceleo.engine.generation.AcceleoEngine.doEvaluate(AcceleoEngine.java:365)
> at
> org.eclipse.acceleo.engine.generation.AcceleoEngine.evaluate(AcceleoEngine.java:142)
> at
> org.eclipse.acceleo.engine.service.AcceleoService.doGenerateTemplate(AcceleoService.java:884)
> at
> org.eclipse.acceleo.engine.service.AcceleoService.doGenerate(AcceleoService.java:575)
> at
> org.eclipse.acceleo.engine.service.AbstractAcceleoGenerator.generate(AbstractAcceleoGenerator.java:193)
> at
> org.eclipse.acceleo.engine.service.AbstractAcceleoGenerator.doGenerate(AbstractAcceleoGenerator.java:158)
> ..
>
> On stdout, I get the following values:
> Attr3: Correct value, as derived from Attr1 and Attr2
> Attr1/2: mailto:org.eclipse.emf.ecore.impl.DynamicEObjectImpl@27979138
> (eClass: mailto:org.eclipse.emf.ecore.impl.EClassImpl@4fbf07d6 (name:
> OclInvalid_Class) (instanceClassName: null) (abstract: false,
> interface: false))
>
> It looks like that Acceleo cannot access Attr1 and Attr2 fields at
> runtime, but I have no idea why. Before Acceleo activation, I checked
> in the Debugger that all three attributes were correctly set for all C
> instances.
>
> Worse, I do not face these issues with the generator that operates on
> D instances.
>
> Were should I start investigating ?
>
> Thanks,
>
> Michaël
>
|
|
| |
Re: [Acceleo] Invalid attributes during template invocation [message #976099 is a reply to message #976005] |
Thu, 08 November 2012 05:07   |
Eclipse User |
|
|
|
Thanks for your replies.
As Laurent suggested, I have added [anInstance/] and [anInstance.oclIsUndefined()/] in my template. The results show that anInstance is always a non-null instance of C.
[anInstance/] sucessfully invokes anInstance.toString() method. Again Attr1, Attr2 and Attr3 values are correct in the resulting string displayed on stdout.
As seen by Java, anInstance is a perfectly valid instance of the C->B->A class.
In OCL, navigation from B(MM2) to A(MM1) classes fails for some reason.
Maybe I got the dependencies wrong betwen my Acceleo plugins and my MM plugins ? From comment 3 of this bug report, I understand that some requirements apply, but they are not always clear to me.
Two examples:
A metamodel and its generated java classes can live in separate plugins. In my Acceleo plugin, which should I register as dependencies ?
In MM2 plugin, MM1 plugin is registered as a dependency. Will Acceleo be able to navigate to MM1 if I only register MM2 as a dependency ?
Regards,
[Updated on: Thu, 08 November 2012 05:44] by Moderator
|
|
| | |
Re: [Acceleo] Invalid attributes during template invocation [message #976259 is a reply to message #976162] |
Thu, 08 November 2012 07:37   |
Eclipse User |
|
|
|
Hi
You are making assumptions that you understand the problem and so you
present a subjective view that makes it impossible to reproduce your
problems.
For instance, you omitted abstract, and you wrote
"On stdout, I get the following values:
Attr3: Correct value, as derived from Attr1 and Attr2
Attr1/2: mailto:org.eclipse.emf.ecore.impl.DynamicEObjectImpl@27979138
(eClass: mailto:org.eclipse.emf.ecore.impl.EClassImpl@4fbf07d6 (name:
OclInvalid_Class) (instanceClassName: null) (abstract: false, interface:
false)) "
This does not look like the output of your transformation.
Please provide a zipped project so that your actual problem can be examined.
Regards
Ed Willink
On 08/11/2012 11:06, Michaël Melchiore wrote:
> I have found a working workaround.
>
> In B class, I added two new attributes AAttr1 and AAttr2.
>
> MM2
> Class B extends A
> Attr3 : String (derived from Attr1 and Attr2)
> AAttr1 : String
> AAttr2 : String[/code]
>
> Then, I have modified BImpl.java so that setAAttr1 and setAAttr2 are
> automatically called within setAttr1 and setAttr2 are invocated (I
> forgot to mention that A is an abtract class so that all its method
> are implemented in B).
>
> In Acceleo templates, I now use AAttr1 and AAttr2 which always mirror
> Attr1 and Attr2 values.
> This strongly indicates that OCL navigation from B to A is the culprit.
|
|
| | | | | |
Re: [Acceleo] Invalid attributes during template invocation [message #976501 is a reply to message #976484] |
Thu, 08 November 2012 11:20   |
Eclipse User |
|
|
|
Hi
That is why we need a reproducible example. It appears that the problem
is not where you think it is and so not in what we have seen.
On these occasions I resort to a kind of binary search.
Take a complete copy of the faulty system and repeatedly delete 50%
until the problem goes away, back up and try a different deletion.
Eventually a small repro emerges and too often an irritation at being so
stupid. Sometimes the irritation can be assuaged slightly by reporting a
bug against some poor error detection.
Regards
Ed Willink
On 08/11/2012 16:09, Michaël Melchiore wrote:
> I have created a small example, but I am unable to reproduce the problem. At least, you can examine it to understand what I am trying to achieve. In a real project, I would have separate templates to deal with B, C and D instances.
>
> test-case-code.tar.gz contains the metamodels, the Acceleo template and launcher projects.
> test-case-model.tar.gz contains a single project with a sample model. Launch Acceleo on it using the popup menu
>
>
> If you have suggestions on how to trigger the faulty behavior, I am listening.
>
> Regards,
>
> Michaël
|
|
| | | | | | | | | | | |
Re: [Acceleo] Invalid attributes during template invocation [message #989077 is a reply to message #989069] |
Tue, 04 December 2012 09:36   |
Eclipse User |
|
|
|
Hi
Knowing what to launch I can see a variety of problems.
Launching an "Acceleo Plugin Application (Default)" runner locks my
Eclipse up; probably
https://bugs.eclipse.org/bugs/show_bug.cgi?id=346233 again.
Launching an "Java Application (Advanced)" gives informative content in
the stack trace.
Exception in thread "main"
org.eclipse.emf.ecore.resource.impl.ResourceSetImpl$1DiagnosticWrappedException:
org.eclipse.emf.ecore.xmi.PackageNotFoundException: Package with uri
'http://example.org/mm2' not found.
(file:/C:/Development/Buck/runtime-New_configuration/org.example.acceleo/tasks/model.mm2,
2, 227)
at
org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.handleDemandLoadException(ResourceSetImpl.java:319)
at
org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoadHelper(ResourceSetImpl.java:278)
at
org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getResource(ResourceSetImpl.java:406)
at
org.eclipse.acceleo.common.utils.ModelUtils.load(ModelUtils.java:361)
at
org.eclipse.acceleo.engine.service.AbstractAcceleoGenerator.initialize(AbstractAcceleoGenerator.java:457)
at org.example.acceleo.Main.<init>(Main.java:90)
at org.example.acceleo.Main.main(Main.java:144)
Caused by: org.eclipse.emf.ecore.xmi.PackageNotFoundException: Package
with uri 'http://example.org/mm2' not found.
(file:/C:/Development/Buck/runtime-New_configuration/org.example.acceleo/tasks/model.mm2,
2, 227)
at
org.eclipse.emf.ecore.xmi.impl.XMLHandler.getPackageForURI(XMLHandler.java:2593)
at
org.eclipse.emf.ecore.xmi.impl.XMLHandler.getFactoryForPrefix(XMLHandler.java:2423)
at
org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObjectByType(XMLHandler.java:1300)
at
org.eclipse.emf.ecore.xmi.impl.XMLHandler.createTopObject(XMLHandler.java:1469)
at
org.eclipse.emf.ecore.xmi.impl.XMLHandler.processElement(XMLHandler.java:1020)
at
org.eclipse.emf.ecore.xmi.impl.XMIHandler.processElement(XMIHandler.java:77)
which is because you have not reacted to the comments in Main.java
telling you how to register your packages.
Looking at your manifests by eye, it looks like you may have a later
problem that mm0 is not exported and so should be invisible.
Your difficulty in reproducing your problem may be because the URI
resolution in Acceleo is inconsistent between the editing and execution
contexts. There is helpful heuristic code that seems to work in simple
cases. Unfortunately in complex cases it seems to add to the debugging
complexity.
I suggest that the Acceleo guys try launching your main.mtl in the
nested Eclipse using the model.mm2 from the nested nested Eclipse. Keep
the org.eclipse.ocl.ecore, that has an inheritance error since
attempting to Run As -> Launch Acceleo Application for main.mtl first
creates a launch but fails to run, and subsequent attempts give an
obsure "Model is missing" diagnostic in the Error Log without any clue
as to the source application. Once the missing model.mm2 is is corrected
in the launch, the "Acceleo Plugin Application (Default)" lock up can be
encountered.
All in all, you provide useful examples of how things can go wrong and
how missing diagnostics can make moderate problems that are very common
user errors very confusing.
If you
a) use "Java Application (Advanced)" runner
b) register your packages in Main.java as commented
c) make your packages visible on the classpath
you might make progress.
Regards
Ed Willink
On 04/12/2012 13:56, Ed Willink wrote:
> Hi
>
> You're getting vague again.
>
> It seems the nested nested Eclipse was just a confusing red herring.
>
> You didn't provide a launch configuration so how do I know what to
> launch and how?
>
> [If you use an "Acceleo Plugin Application (Default)" runner, the
> problem is solved; it never works for me. I only use "Java Application
> (Advanced)".]
>
> Regards
>
> Ed Willink
>
>
> On 04/12/2012 13:09, Michaël Melchiore wrote:
>> As stated in my first post, I am working with Eclipse 3.6.2 and EMF
>> 2.6.1. I could try to run the test case in a updated Eclipse
>> installation. But this will not be an option for my real work. Do
>> Helios packages still receive bug fixes ?
>>
>> The org.eclipse.ocl.ecore plug-in copy was there so that I could step
>> through its code with the java debugger. I will edit my previous
>> posts so that it is no longer provided in the corresponding archive.
>>
>> Regarding the other plugins I chose to provide, I think this is
>> purely a matter of personal view. I wanted the examples to run "out
>> of the box" so that kind helpers can use them quickly. You want the
>> least amount of nose possible. This is a different, yet perfectly
>> valid, point of view on the matter of test case packaging.
>>
>> The problem I am trying the reproduce is the
>> java.lang.IllegalArgumentException exception that is thrown by
>> Acceleo during code generation (see my first post).
>> Thanks for your help
>>
>> Michaël
>>
>>
>>
>
|
|
|
Re: [Acceleo] Invalid attributes during template invocation [message #989084 is a reply to message #989069] |
Tue, 04 December 2012 10:05   |
Eclipse User |
|
|
|
No, the nested nested Eclipse is not a red herring.
I built this example trying to mimic the real code I am working on. From the feedback I received in this thread, my issue seems to involve metamodel resolving and navigation. I have two different kinds of metamodels :
- installed in Eclipse
- contained in a workspace plugin
Precisely, I have defined a few classes, which are organized in several metamodels spread across different plugins in my workspace. All these classes inherit from a single class. In my use case, issues arise when I try to access the root class attributes from children class instances in Acceleo. The only distinguishing feature of the root class is that it is the only class which metamodel that is not contained in my workspace.It is is installed in Eclipse.
The nested nested Eclipse was the only way I found to reproduce the situation. In the test case, MM0 contains the root class Z, while MM1, 2 and 3 define children classes of Z.
If MM0, 1, 2 and 3 all live in the same workspace, the Acceleo generation run without error. I simply launch an Eclipse application, create an example project and launch generation using Acceleo launcher popup menu entry.
To reproduce my issue, I had to find a trick so that MM0 looks "installed" from MM1, 2 and 3 point of view. This is why MM0 has its own workspace.
Workspace0
ProjectMM0
EclipseApplication1
Workspace1
ProjectMM1
ProjectMM2
ProjectMM3
EclipseApplication2
Workspace2
ProjectWithExampleModel
All EclipseApplication use default launch settings besides setting the right workspace locations.
I hope this helps. English is not my native language, I am trying my best to be clear.
[Updated on: Tue, 04 December 2012 10:07] by Moderator
|
|
| |
Re: [Acceleo] Invalid attributes during template invocation [message #1011849 is a reply to message #997699] |
Wed, 20 February 2013 06:11   |
Eclipse User |
|
|
|
Michael,
I had mistakenly thought that this thread was resolved, please forgive the long delay. Do not hesitate to "ping" us by commenting on your forum threads if they stale too long, chances are we overlooked them.
Trying to untangle the useful information from the noise was a little hard, but here are the steps I settled on to try this :
- download a new "eclipse classic" bundle
- launch this eclipse, install the corresponding EMF version (2.6 in Helios, 2.7 in Indigo, did not try others) along with Acceleo 3.4.0 (http://download.eclipse.org/releases/kepler), restart eclipse
- import eclipse-0-projects
- "run > Run Configurations..." create a new "Eclipse application", change the Xmx and MaxPermSize to more intelligent values that the default (-Xmx512m -XX:MaxPermSize=256m)
- import eclipse-1-projects in the second eclipse
- "run > Run Configurations..." create a new "Eclipse application", change the Xmx and MaxPermSize as well as the workspace location (appended "2" at the end of the default)
- import eclipse-2-projects in the third eclipse
- right-click /org.example.model/model/model.mm2 > Acceleo > Generate Acceleo
This works without a hitch in Indigo. I then went back to Helios using the same steps.
The first try resulted in java.lang.NoClassDefFoundError: org/eclipse/ocl/helper/OCLSyntaxHelper . Somehow, using the Kepler update site to install Acceleo in Helios resulted in me having "org.eclipse.ocl" version 3.0 and "org.eclipse.ocl.ecore" version 3.2... which is totally incoherent.
I then repeated the steps using the Acceleo update site directly instead of Kepler, which resulted in a sound installation (o.e.ocl 3.0.2 and o.e.ocl.ecore 3.0.2). This indeed fails in IllegalArgumentException.
Since these two were using the very same steps with the same versions of Acceleo, my very first guess is that it was a bug in OCL that's been fixed somewhere on the road between Helios and Juno. However, I will still try again with my Indigo install but without the Kepler update site (to avoid updating OCL along with Acceleo).
|
|
|
Re: [Acceleo] Invalid attributes during template invocation [message #1011891 is a reply to message #1011849] |
Wed, 20 February 2013 07:42   |
Eclipse User |
|
|
|
Short version :
this was a bug in either OCL or EMF, fixed for Juno. If you cannot update to Juno, we'll have to try and understand _exactly_ what bug this was. I'll try and debug one of the failing instances.
Long version :
Following my first hunch, I repeated these very same steps with Indigo (3.7.2) but using the Acceleo update site instead of Kepler. This indeed resulted in the IllegalArgumentException you mentionned.
The only two bundles from OCL that were installed were the dependencies of Acceleo :
- org.eclipse.ocl 3.1.0_v20120206-0606
- org.eclipse.ocl.ecore 3.1.2_20111015-2027
This is what could be found by p2 without changing the update sites and leaving the "contact all update sites" box ticked when installing Acceleo. After this first "failing" test, I closed the two nested Eclipses and, in the first, I installed the OCL SDK 3.1.2 through the Indigo update site. Versions of OCL are now :
- org.eclipse.ocl 3.1.0_v20120206-0606 (unchanged)
- org.eclipse.ocl.doc 3.1.1_v20120206-0606
- org.eclipse.ocl.ecore 3.1.2_20111015-2027 (unchanged)
- org.eclipse.ocl.ecore.edit 3.1.0_20110526-1523
- org.eclipse.ocl.edit 3.1.0_v20120206-0606
- org.eclipse.ocl.uml 3.1.0_v20120206-0606
- org.eclipse.ocl.uml.edit 3.1.0_20110526-1523
This still fails in IllegalArgumentException.
Afterwards, I tried to update OCL through the OCL maintenance update site (Ed, I believe this is the correct update site for Juno SR2 release candidates)? However, OCL as a whole depends on UML, which evolved to 4.0 in Juno, and which in turn depends on EMF 2.8.
Acceleo only depends on the "ecore" part ... but the OCL update site does not allow us to avoid the UML dependency. As such, I needed to switch back to using the Juno update site in order to update the OCL End-User SDK to 4.0.2. After the update, your example works fine.
OCL versions range from 1.0.0 (? common and common UI) to 4.0.0 (for the UML support).
This is a bug in either EMF or OCL. It has been fixed for Juno, but I have no idea exactly how, or when. Some debugging might shed some light on this.
|
|
|
Re: [Acceleo] Invalid attributes during template invocation [message #1011951 is a reply to message #1011891] |
Wed, 20 February 2013 10:22   |
Eclipse User |
|
|
|
Okay, the "bug was fixed in Juno" is wrong. All that's done in Juno is that OCL now ignores the failures silently (http://git.eclipse.org/c/mdt/org.eclipse.ocl.git/tree/plugins/org.eclipse.ocl.ecore/src/org/eclipse/ocl/ecore/EcoreEvaluationEnvironment.java#n248).
What you have is basically EMF screwing us.
mm1.ecore references mm0.ecore through a "platform:/plugin" URI. Naturally, when OCL compiles the call to "aB.Attr", it references "Attr" through that same URI when compiling : platform:/plugin/org.example.mm0/model/mm0.ecore#//Z/Attr . However, when loading the model later on, it references its metamodel through the "normal" way, the NsURI. Then, we end up with Ed's beloved "metamodel schyzophrenia" : MM0 is loaded through two distinct means : the module references it as "platform:/plugin/org.example.mm0/model/mm0.ecore", the model references it through "http://example.org/mm0". This never ends well.
The problem lies at compile time, because mm1.ecore references mm0 through "platform:/plugin" instead of referencing it through its NsURI.
The best workaround I can give you is to register the mapping from "platform:/plugin/org.example.mm0/model/mm0.ecore" to "http://example.org/mm0". i.e. if I add this in your Main#registerPackage() then the generation works resourceSet.getURIConverter().getURIMap().put(URI.createURI("platform:/plugin/org.example.mm0/model/mm0.ecore"), URI.createURI(Mm0Package.eNS_URI)); .
Ed, I think one of the EcorePlugin or EcoreUtil methods could do this automatically?
Laurent Goubet
Obeo
[Updated on: Wed, 20 February 2013 10:26] by Moderator
|
|
|
Re: [Acceleo] Invalid attributes during template invocation [message #1011986 is a reply to message #1011951] |
Wed, 20 February 2013 11:22   |
Eclipse User |
|
|
|
On 20/02/2013 15:22, Laurent Goubet wrote:
> Ed, I think one of the EcorePlugin or EcoreUtil methods could do this
> automatically?
Hi Laurent
Assuming you mean Ed W rather than Ed M, ...
From my comments on
https://bugs.eclipse.org/bugs/show_bug.cgi?id=360926#c7, the default EMF
Eclipse-hosted (Acceleo compile/edit-time) behaviour is correct. All
URIs should be correctly normalized to the many locations underlying
platform:/resource and platform:/plugin
The problem arises through reuse of the same URIs in a standalone
environment. You must re-establish the same platform:/resource,
platform:/plugin normalization. Acceleo and other tools have heuristics
that make ../.. sort of work for the easy cases, but that make the
failures even worse and more obscure for the harder, particularly
multi-GIT cases.
I created StandaloneProjectMap to re-establish that normalization.
Subsequently, 27-Oct-2012, similar functionality has become available in
EcorePlugin.computePlatformURIMap and similar, so I strongly recommend
Acceleo to revisit all its URI heuristics, since with a correct
normalization, EMF URIs work beautifully rather than "basically EMF
screwing us". There is nothing fundamentally clever in
StandaloneProjectMap so it could easily be back-ported to support
Helios. EcorePlugin.computePlatformURIMap exploits a variety of minor
API relaxations that mandate the associated EMF classes.
Regards
Ed Willink
|
|
|
Re: [Acceleo] Invalid attributes during template invocation [message #1012256 is a reply to message #1011986] |
Thu, 21 February 2013 03:03   |
Eclipse User |
|
|
|
Ed Willink wrote on Wed, 20 February 2013 11:22
> Ed, I think one of the EcorePlugin or EcoreUtil methods could do this
> automatically?
Hi Laurent
Assuming you mean Ed W rather than Ed M, ...
yup 
Ed Willink wrote on Wed, 20 February 2013 11:22
From my comments on
https://bugs.eclipse.org/bugs/show_bug.cgi?id=360926#c7, the default EMF
Eclipse-hosted (Acceleo compile/edit-time) behaviour is correct. All
URIs should be correctly normalized to the many locations underlying
platform:/resource and platform:/plugin
The problem arises through reuse of the same URIs in a standalone
environment. You must re-establish the same platform:/resource,
platform:/plugin normalization. Acceleo and other tools have heuristics
that make ../.. sort of work for the easy cases, but that make the
failures even worse and more obscure for the harder, particularly
multi-GIT cases.
Though no one said anything about standalone here. The compilation occurs within Eclipse, the generation too. Both called from within running Eclipse bundles.
The problem here is that mm1.ecore references mm0.ecore through "platform:/plugin". When we load mm1.ecore, that reference is preserved as-is. However, EMF decides _not_ to use this kind of reference when it loads mm1.ecore as an EPackage itself. The reference, then, is made through the NsURI instead of the xmi's platform URI. How? It is established from the MM1PackageImpl#initializePackageContents() through this code
Mm0Package theMm0Package = (Mm0Package)EPackage.Registry.INSTANCE.getEPackage(Mm0Package.eNS_URI);
aEClass.getESuperTypes().add(theMm0Package.getZ());
instead of going through the "normal" resource set URI normalization.
Thus, we either :
- need a way to tell EMF that the "platform:/plugin" reference is equivalent to a given nsURI. That's one more "magic" conversion to add in the URIConverter, and seems sub-optimal. This is the workaround I proposed to Michael, and the easiest to set up.
- need to be able to tell Acceleo/OCL, at compile time, that it should use the NsURI instead of the platform:/plugin URI to reference metamodel artefacts. This seems like the best course of action.
Acceleo's "target" metamodel, in the current case, is mm2. mm2 references mm1 that in turn references mm0. All references are in the form of "platform" URIs. For the first (mm2 to mm1), both ecores are in the workspace. Acceleo already kicks in here to replace the platform/resource URI with the NsURI in the compiled emtl file. So that reference does not end in a metamodel being loaded twice. However, for the second (mm1 to mm0), mm0 lies in the plugins, and Acceleo does not force that (platform/plugin) URI into an nsURI... that might be where we should plug ourselves.
Laurent Goubet
Obeo
|
|
|
Re: [Acceleo] Invalid attributes during template invocation [message #1012331 is a reply to message #1012256] |
Thu, 21 February 2013 06:10   |
Eclipse User |
|
|
|
Hi Laurent
I think EMF is still consistent.
Anything that is loaded as compiled Java is referenced by nsURI.
Anything loaded as a *.ecore file is referenced as platform:/...
For Acceleo this should work provided the original import is
consistently platform:/... rather than an http:/... 'helpfully'
discovered to be platform:/...
I notice that one of my transformations is:
[module
org::eclipse::ocl::examples::build::acceleo::generateXBNF2LPG('http://www.eclipse.org/ocl/XBNF','http://www.eclipse.org/emf/2002/Ecore')/]
even though http://www.eclipse.org/ocl/XBNF has never been genmodelled.
IMHO this is a bug. I should have to specify
platform:/resource/org.eclipse.ocl.examples.xtext2lpg/model/XBNF.ecore.
IMHO it also unhelpful and wasteful for Accelo to scan *.ecore on the
classpath to discover possible nsURIs. At any rate Acceleo should be
aware that http://www.eclipse.org/ocl/XBNF was discovered in
platform:/resource/org.eclipse.ocl.examples.xtext2lpg/model/XBNF.ecore
and generate references accordingly.
<referredProperty xsi:type="ecore:EReference"
href="http://www.eclipse.org/ocl/XBNF#//Syntax/grammars"/>
is wrong. There is no Java-loadable http://www.eclipse.org/ocl/XBNF.
For code generation it can be more troublesome, a *.ecore is loaded and
converted to *.java. ProjectMap supports this by allowing a potentially
three-way metamodel schizophrenia between platform:/resource/...,
platform:/plugin/..., http:/... to be mediated by cross-mapping EPackage
registry entries. (The EcorePlugin enhancements don't support this.). So
for default usage, loading *.ecore with an nsURI that has a Java package
causes the Java package resource to be returned. With ProjectMap you
should only be able to have metamodel schizophrenia where you
specifically enable it.
Regards
Ed
On 21/02/2013 08:03, Laurent Goubet wrote:
> Ed Willink wrote on Wed, 20 February 2013 11:22
>> > Ed, I think one of the EcorePlugin or EcoreUtil methods could do
>> this > automatically?
>> Hi Laurent
>>
>> Assuming you mean Ed W rather than Ed M, ...
>
>
> yup :)
>
> Ed Willink wrote on Wed, 20 February 2013 11:22
>> From my comments on
>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=360926#c7, the default
>> EMF Eclipse-hosted (Acceleo compile/edit-time) behaviour is correct.
>> All URIs should be correctly normalized to the many locations
>> underlying platform:/resource and platform:/plugin
>>
>> The problem arises through reuse of the same URIs in a standalone
>> environment. You must re-establish the same platform:/resource,
>> platform:/plugin normalization. Acceleo and other tools have
>> heuristics that make ../.. sort of work for the easy cases, but that
>> make the failures even worse and more obscure for the harder,
>> particularly multi-GIT cases.
>
>
> Though no one said anything about standalone here. The compilation
> occurs within Eclipse, the generation too. Both called from within
> running Eclipse bundles.
>
> The problem here is that mm1.ecore references mm0.ecore through
> "platform:/plugin". When we load mm1.ecore, that reference is
> preserved as-is. However, EMF decides _not_ to use this kind of
> reference when it loads mm1.ecore as an EPackage itself. The
> reference, then, is made through the NsURI instead of the xmi's
> platform URI. How? It is established from the
> MM1PackageImpl#initializePackageContents() through this code
>
> Mm0Package theMm0Package =
> (Mm0Package)EPackage.Registry.INSTANCE.getEPackage(Mm0Package.eNS_URI);
> aEClass.getESuperTypes().add(theMm0Package.getZ());
>
> instead of going through the "normal" resource set URI normalization.
>
> Thus, we either :
> - need a way to tell EMF that the "platform:/plugin" reference is
> equivalent to a given nsURI. That's one more "magic" conversion to add
> in the URIConverter, and seems sub-optimal. This is the workaround I
> proposed to Michael, and the easiest to set up.
> - need to be able to tell Acceleo/OCL, at compile time, that it should
> use the NsURI instead of the platform:/plugin URI to reference
> metamodel artefacts. This seems like the best course of action.
>
> Acceleo's "target" metamodel, in the current case, is mm2. mm2
> references mm1 that in turn references mm0. All references are in the
> form of "platform" URIs. For the first (mm2 to mm1), both ecores are
> in the workspace. Acceleo already kicks in here to replace the
> platform/resource URI with the NsURI in the compiled emtl file. So
> that reference does not end in a metamodel being loaded twice.
> However, for the second (mm1 to mm0), mm0 lies in the plugins, and
> Acceleo does not force that (platform/plugin) URI into an nsURI...
> that might be where we should plug ourselves.
>
> Laurent Goubet
> Obeo
|
|
| | | | |
Re: [Acceleo] Invalid attributes during template invocation [message #1013065 is a reply to message #1013053] |
Fri, 22 February 2013 12:40   |
Eclipse User |
|
|
|
Hi Michael
I fought against these problems, and mostly won, for some MDT/OCL
auto-generation where I had the extra challenge that I was
auto-generating new OCL from development OCL while Acceleo was executing
installed OCL.
It can be done, but you have to outwit Acceleo's helpful heuristics. My
main weapon was my ProjectMap class that eliminated the distinction
between the three forms of model reference. Thereafter a minor override
of some URL creation methods in the initialization and the problem was
solved.
You can find the relevant scripts in org.eclipse.ocl.examples.build.
Note that all the invocations are from MWE scripts, so what you find in
the auto-generated main's is only part of the story.
Don't even look at the code unless you are prepared to have a couple of
very trying days before you achieve success.
Regards
Ed Willink
On 22/02/2013 17:18, Michaël Melchiore wrote:
> Sadly, I think this situation is nearly unavoidable when designing
> frameworks with Acceleo as a code generation backend.
>
> As I understand it, Acceleo workflow naturally produces a significant
> amount of metamodels. Users are encouraged to build detailed
> metamodels to simplify template code. Moreover, different generation
> requirements should be adressed by refining metamodels.
>
> Finally, users are often required to subclass some public API classes
> to plug their work in the framework workflow.
>
>
> I have started the process of recreating the problematic situation in
> my product so that I can test your fix. I am running into transient
> compilation errors as Acceleo fails to load the plugin-contained
> metamodel. I have noticed the following changes seem to matter:
>
>
> in workspace metamodels, switch external metamodel imports between
> "../../*" and "platform:/resource|plugin" URI scheme
> on Acceleo projects, switch between"workspace relative" and "absolute
> file system" compilation path kind
>
> Could you provide me with some guidelines on those settings ? From
> Acceleo best practice pages, I just recall that all my Acceleo
> projects should be set to XMI module serialization format.
|
|
| | | | | | |
Re: [Acceleo] Invalid attributes during template invocation [message #1015598 is a reply to message #1015389] |
Fri, 01 March 2013 05:37   |
Eclipse User |
|
|
|
Michaël,
Just double-checked from my end ... Seems like I had done something else when tinkering with your samples, since it indeed does not work. EMF will not use the normalized URI when checking if an URI is that of an ePackage in the resource resolution process.
So the only workaround for this is to change the way your models reference themselves, i.e. open "mm1.ecore" textually, and replace occurences of "platform:/plugin/org.example.mm0/model/mm0.ecore" with "http://example.org/mm0" (leave the fragments "#..." intact, only change the ecore URI). Ed mentionned that
Quote:href="http://www.eclipse.org/ocl/XBNF#//Syntax/grammars" is wrong. ... but that is exactly how EMF references metamodels, and it makes use of a specific handling for such URIs (which is part of why your use case is failing).
The only impact you will see after having done this is that when you open "mm1.ecore" in the ecore editor, you will not "see" a tree node for the "mm0" resource. It will remain hidden. That is the only change : you will still be able to reference parts of that other metamodel, you will still be able to edit and save your model. Once you've change the platform URI once, you won't have to do it again after edits. You will also need to recompile the mtl file since the references there will react to the change in mm1 too.
As I previously mentionned, we can implement changes in Acceleo to allow for this uses case without forcing this cumbersome workaround on you, but that is not a planned change yet.
Laurent Goubet
Obeo
|
|
| | | | | | | | | | | | | | |
Goto Forum:
Current Time: Wed Mar 26 04:27:00 EDT 2025
Powered by FUDForum. Page generated in 0.12164 seconds
|