EMFTVM: Transformation not terminating in Standalone Mode [message #1738342] |
Tue, 19 July 2016 03:59  |
Eclipse User |
|
|
|
Hello,
I wrote a refining transformation that would create a custom trace model as second output.
For this purpose I created a simple Trace metamodel which just contains a trace root container and a trace class, that stores a source and a target value, both Strings.
During the transformations I would create trace elements, which I add to the container through an endpoint rule, to make sure all the elements are created.
When the transformation is run in my eclipse it terminates in 0.5 seconds. When it's run in a standalone application it does not terminate at all (been running > 5 min now)
I suspect it's the endpoint rule that causes the trouble, but I don't know why. Here's the code:
-- @atlcompiler emftvm
-- @nsURI EMFTVM=http://www.eclipse.org/m2m/atl/2011/EMFTVM
-- @path NodeSet=/metamodel/NodeSet.ecore
-- @path Trace=/metamodel/MyTrace.ecore
module ChangeNodeId;
create OUT: NodeSet, TRACE: MyTrace refining IN: NodeSet;
helper def : traceList : Sequence(MyTrace!Trace) = Sequence{};
helper def : traceModel : MyTrace!Traces = OclUndefined;
-- root rule: create trace container
rule Traces {
from
s : NodeSet!NodeSetType
to
t : NodeSet!NodeSetType,
traceModel : MyTrace!Traces
do {
thisModule.traceModel <- traceModel;
}
}
-- change something, create trace of change
rule ChangeNodeId {
from
s : NodeSet!Variable
to
t : NodeSet!Variable (
nodeId <- thisModule.generateNodeId(source.nodeId)
),
trace : MyTrace!Trace (
source <- source.nodeId
)
do {
trace.target <- target.nodeId;
thisModule.traceList <- thisModule.traceList -> append(trace);
}
}
-- add traces to container
endpoint rule addTraces() {
do {
thisModule.traceModel.traces <- thisModule.traceList;
}
}
When I remove the endpoint rule the transformation also terminates in standalone mode, but now I don't know, how I can add the created traces to the container. I also tried something like this: I would like to iterate over all source elements, get the trace (if one was created), and add it to the container.
-- root rule: create trace container
rule Traces {
from
s : NodeSet!NodeSetType
to
t : NodeSet!NodeSetType,
traceModel : MyTrace!Traces (
traces <- NodeSet!Node.allInstances() -> select(i | not thisModule.resolveTemp(i, 'trace').oclIsUndefined()) -> collect(e | thisModule.resolveTemp(e, 'trace'))
)
}
but here I can't figure out how to find the created traces. This throws an VMException: Cannot resolve default trace target, when not every element has a trace.
I could obviously make it mandatory to create a trace for every source element, but I would rather look for another solution first.
[Updated on: Tue, 19 July 2016 04:01] by Moderator
|
|
|
|
Re: EMFTVM: Transformation not terminating in Standalone Mode [message #1738505 is a reply to message #1738498] |
Wed, 20 July 2016 08:29   |
Eclipse User |
|
|
|
Hi Dennis,
thank you for your reply.
1) Since I was running the transformation in an OSGi environment I didn't notice that it's actually indeed terminating. If I run it as a java application I can see that it throws a StackOverflowException.
Exception in thread "main" java.lang.StackOverflowError
at org.eclipse.m2m.atl.emftvm.util.LazyCollection$AppendIterator.<init>(LazyCollection.java:406)
at org.eclipse.m2m.atl.emftvm.util.LazyList$AppendList.iterator(LazyList.java:383)
at org.eclipse.m2m.atl.emftvm.util.OCLOperations$ResolveList$ResolveIterator.<init>(OCLOperations.java:69)
at org.eclipse.m2m.atl.emftvm.util.OCLOperations$ResolveList.iterator(OCLOperations.java:119)
at org.eclipse.m2m.atl.emftvm.util.LazyCollection$WrappedIterator.<init>(LazyCollection.java:90)
at org.eclipse.m2m.atl.emftvm.util.LazyCollection$AppendIterator.<init>(LazyCollection.java:407)
at org.eclipse.m2m.atl.emftvm.util.LazyList$AppendList.iterator(LazyList.java:383)
at org.eclipse.m2m.atl.emftvm.util.OCLOperations$ResolveList$ResolveIterator.<init>(OCLOperations.java:69)
at org.eclipse.m2m.atl.emftvm.util.OCLOperations$ResolveList.iterator(OCLOperations.java:119)
at org.eclipse.m2m.atl.emftvm.util.LazyCollection$WrappedIterator.<init>(LazyCollection.java:90)
at org.eclipse.m2m.atl.emftvm.util.LazyCollection$AppendIterator.<init>(LazyCollection.java:407)
at org.eclipse.m2m.atl.emftvm.util.LazyList$AppendList.iterator(LazyList.java:383)
Again, if I remove the endpoint rule, everything works just fine.
2) Yes, I think I do. I want to keep track of attributes that changed. With the EMFTVM trace model I can only find out which object changed, but not which value the attribute of the element had before it was changed. (In this simple case above, I want to keep track of the change on the NodeId Attribute)
Of course, if you are aware of a better way to achieve this, please let me know.
3) Yes, I'm aware of that. While looking into custom traces I found this solution: https://wiki.eclipse.org/ATL/Design_Patterns#Custom_Tracing. I tried to follow this idea and just use it as second output model (encapsulated in my simple trace model).
Quote:The simplest way to deal with this is to extract the ChangeNodeId rule's filter expression into a helper attribute defined on the rule's source element, so that you can reuse the same helper attribute in the Traces rule
This is a good idea. Will this also work if other rules would create traces as well? I fear this might get very confusing and I feel like using the trace model reflection might be the cleanest way. I will look into both options.
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.05958 seconds