Today I tried to edit an Ecore/Generator model used in the VIATRA2 framework, but the system greated me with an error screen stating, there are 4 errors in the selected Genmodel.
The error messages were a little bit cryptic (but all similar in nature): A containment reference of a type with a container feature platform:/resource/org.eclipse.viatra2.gtasm.model/model/gtasmmodel.ecore#//gtasm/metamodel/gt/GTPattern/namespace that requires instances to be contained elsewhere cannot be populated.
This was scary, as I don’t remember any new core features in EMF 2.6, that suggest such changes. My second guess was a misedited model, but after checking, that I have the same models as half year ago, this proved wrong. Even worse, these errors did not appear in either the Problems or Error log view. Checking the items mentioned in the error messages did not help, as the model elements looked “innocent enough” not to question their content.
It was only know when I saw that these errors are shown in a new, problem page in the editor (I often miss the editor pages option – except on form-based editors), and on the other page the tree is displayed, and code generation seemed also working.
At this point I looked on the internet for similar problems, and found a thread about the issue in the EMF newsgroup. The main idea was Ed Merks’s comment:
The point is supposed to be that you can’t be contained by more than one container, so you can’t have a container references that’s required as well as any other containment reference that’s not the opposite of that required container. I.e., a required container prevents other containment references from ever being populated.
Using this information I finally understood, what the error message meant, and begin looking for the cause in the Ecore model. After some searching (the error message only mentioned one model element from the three actors, and it is hard to get an overview of the inter modelelement relations in an EMF tree editor), I finally found the mentioned elements, that looked quite innocent at first – just take a look at the included graphical representation.
We have a machine, that contains both patterns and rules, while rules may contain addition pattern definitions (named local pattern definitions). On the other hand, patterns and rules have a backreference to the machine (namespace). As we wanted to have the Machine reference available for local patterns, the pattern references exactly one machine.
The drawback of the solution is, that the machine reference is the inverse of the containment relation, so every pattern has to be contained in a machine. On the other hand, EMF requires that every EObject (not EClass) must have exactly one incoming containment reference for serialization, so it is not possible for a rule to be the container of a pattern – hence the error message.
This analysis is extremely useful: it shows, that our metamodel prevents having serializable models in some cases, which comes in handy (I wouldn’t like to be the one, who has to debug such an error after a runtime exception is caught…). The fix is not really straightforward, as this model is already used (interesting fact, that the issue has not been produced in runtime – this means, we don’t have 100% test coverage :)), but by having a map to the error it is easier to fix.
I’d like to thank for the EMF team for this fine analysis solution, but some minor additions: don’t add warnings to a new page, use the existing reporting options; and try to rephrase the message for it to become more understandable.
It turned out the GenModel itself had this problem too. A GenPackage was required to be contained by a GenModel, but there was also a subpackages relation that allowed it to be contained by another GenPackage.