Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Problems with dynamic AND generated EMF(Problems with dynamic creation of instances of classes, that have supertypes with implemented (generated) classes.)
Problems with dynamic AND generated EMF [message #517974] Tue, 02 March 2010 16:06 Go to next message
Janos Kutscherauer is currently offline Janos KutscherauerFriend
Messages: 9
Registered: July 2009
Junior Member
Hi,
I discovered two problems with EMF when it comes to combined dynamic and generated metamodels.
(Although i'm sure that i am not the first one to have trouble with it, i couldn't find any hints to those topics yet...)

I have a metamodel B, from which i want to create instances reflectively. I.e., i do not have implementations generated for B. However, some classes have superclasses from another metmodel A, for which i have the (generated) implementation classes.

Problem 1: Dynamic creation
When i attempt to dynamically create an instance object from a (non-abstract) EClass defined in model B, this fails when this class has an _abstract_ supertype in model A.
It goes like this:

	EClass eClass = ...;  // my EClass from model B
	EObject eObject = classifier.getEPackage().getEFactoryInstance().create(eClass);


The reason for this problem apparently is, that the dynamic factory tries to instantiate a supertype with an implementation class available. This supertype implementation is indeed found in my model A, and so the call is delegated to the factory of my model A. But because this supertype class is declared to be _abstract_, the class cannot be created.
My workaround for now is, as poor as it sounds, not to use abstract types in my generated model!

Is this issue a well-known issue? And what are the perspectives and possible workarounds here?

Problem 2: Features
This problem directs the same structure as described above. Here i have successfully created an instance object from a EClass of model B, which has a supertype in model A.
When i now want to set a value to a feature of this dynamic EObject, EMF accidentally directs the wrong feature which leads to useless models or, more likely, to ClassCastExceptions.
This issure is a bit more complex to explain:
I have an EClass from my (non-generated) model B, let's say "B.E". This class has two supertypes from model A (for which generated implementation classes exist), let's say "A.X" and "A.Y". "A.X" has a feature "int" of type EInteger, and "A.Y" has a feature "string" of type EString.
Now i create an instance object of the class "B.E" and want to set the feature "string='helloworld'".

	EClass eClass = (EClass) ePackage.getEClassifier("E"); // get the EClass 'B.E' from model B
	EObject eObject = eClass.getEPackage().getEFactoryInstance().create(eClass);
	EAttribute stringAttribute = (EAttribute) eClass.getEStructuralFeature("string");
	eObject.eSet(stringAttribute, "helloworld");  // fails with ClassCastException


This fails with ClassCastException for the following reason:
When i create an instance of "B.E" dynamically, as mentioned above, EMF instantiates a supertype and letting this object know, that it actually is a "B.E". In my case, when i dynamically create a "B.E" instance, EMF actually creates an "A.X" instance, as there exists an implementation class. (The reason for chosing "A.X" to be instantiated, and not "A.Y" is simply, that "A.X" appears first in the supertype list). So when the "eSet" method is called on the "A.X" instance (which dynamically should be an "B.E"!), the EAttribute with name "string" and of type "EString" is resolved only by it's ID. And here it crashes: In the type "A.Y", the feature "string" has the ID=0. In "A.X", the feature "int" has also the ID=0. Invoking "eSet" with the feature "string" (with ID=0) and the value "helloworld" causes the resolution of a feature in "A.X" with ID=0 --> which is: "int"! The value "helloworld" is thus assigned to an EInteger feature, which clashes.


I did my best to explain the trouble which occurs here... i know it is complicated but i hope the core problem is a little bit to understand. I'll try to summarize:

EMF attempts to use instances of supertypes with implementation, when a type is instantiated dynamically. This leads to two problems:
1. Abstract supertypes with implementation classes are attempted to be instantiated, which fails. (This problem can be worked around by not using abstract supertypes, but that shouldn't be actually called a workaround really!)
2. Setting (and also getting!) of features fails, when a dynamic class has multiple (implemented) supertypes.


If any of the problems 1 or 2 seem familar to you guys, i'd be really pleased to hear about your thoughts and recommendations.

Best regards
Janosch
Re: Problems with dynamic AND generated EMF [message #517983 is a reply to message #517974] Tue, 02 March 2010 16:21 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33113
Registered: July 2009
Senior Member
Janosch,

Comments below.

Janosch wrote:
> Hi,
> I discovered two problems with EMF when it comes to combined dynamic
> and generated metamodels.
> (Although i'm sure that i am not the first one to have trouble with
> it, i couldn't find any hints to those topics yet...)
>
> I have a metamodel B, from which i want to create instances
> reflectively. I.e., i do not have implementations generated for B.
> However, some classes have superclasses from another metmodel A, for
> which i have the (generated) implementation classes.
>
> Problem 1: Dynamic creation
> When i attempt to dynamically create an instance object from a
> (non-abstract) EClass defined in model B, this fails when this class
> has an _abstract_ supertype in model A.
> It goes like this:
>
> EClass eClass = ...; // my EClass from model B
> EObject eObject =
> classifier.getEPackage().getEFactoryInstance().create(eClass );
>
> The reason for this problem apparently is, that the dynamic factory
> tries to instantiate a supertype with an implementation class
> available. This supertype implementation is indeed found in my model
> A, and so the call is delegated to the factory of my model A. But
> because this supertype class is declared to be _abstract_, the class
> cannot be created.
> My workaround for now is, as poor as it sounds, not to use abstract
> types in my generated model!
Yes, that's the only way.
>
> Is this issue a well-known issue?
Well known to me. :-P
> And what are the perspectives and possible workarounds here?
Only the one you've already tried. The instance created for B must be
compatible with the generated A model. Therefore the instance class
created must implement the generated interfaces of A. Only be reusing a
generated class from A will that be possible. (I played around many
years ago with Java dynamic proxies, but that's another story.)
>
> Problem 2: Features
> This problem directs the same structure as described above. Here i
> have successfully created an instance object from a EClass of model B,
> which has a supertype in model A.
> When i now want to set a value to a feature of this dynamic EObject,
> EMF accidentally directs the wrong feature which leads to useless
> models or, more likely, to ClassCastExceptions.
> This issure is a bit more complex to explain:
> I have an EClass from my (non-generated) model B, let's say "B.E".
> This class has two supertypes from model A (for which generated
> implementation classes exist), let's say "A.X" and "A.Y". "A.X" has a
> feature "int" of type EInteger, and "A.Y" has a feature "string" of
> type EString.
Yes, that's probably number two. Again, the instance we create must
implement both the generated interfaces, but there is no existing class
that does this and so we're stuck with a problem that's impossible to solve.
> Now i create an instance object of the class "B.E" and want to set the
> feature "string='helloworld'".
>
> EClass eClass = (EClass) ePackage.getEClassifier("E"); // get the
> EClass 'B.E' from model B
> EObject eObject =
> eClass.getEPackage().getEFactoryInstance().create(eClass);
> EAttribute stringAttribute = (EAttribute)
> eClass.getEStructuralFeature("string");
> eObject.eSet(stringAttribute, "helloworld"); // fails with
> ClassCastException
>
> This fails with ClassCastException for the following reason:
> When i create an instance of "B.E" dynamically, as mentioned above,
> EMF instantiates a supertype and letting this object know, that it
> actually is a "B.E". In my case, when i dynamically create a "B.E"
> instance, EMF actually creates an "A.X" instance, as there exists an
> implementation class. (The reason for chosing "A.X" to be
> instantiated, and not "A.Y" is simply, that "A.X" appears first in the
> supertype list). So when the "eSet" method is called on the "A.X"
> instance (which dynamically should be an "B.E"!), the EAttribute with
> name "string" and of type "EString" is resolved only by it's ID. And
> here it crashes: In the type "A.Y", the feature "string" has the ID=0.
> In "A.X", the feature "int" has also the ID=0. Invoking "eSet" with
> the feature "string" (with ID=0) and the value "helloworld" causes the
> resolution of a feature in "A.X" with ID=0 --> which is: "int"! The
> value "helloworld" is thus assigned to an EInteger feature, which
> clashes.
Even if this worked, it would not be possible to cast the created
instance of A.X and A.Y so you really won't be able to use that instance
where you'd expect it to be valid.
>
>
> I did my best to explain the trouble which occurs here... i know it is
> complicated but i hope the core problem is a little bit to understand.
> I'll try to summarize:
>
> EMF attempts to use instances of supertypes with implementation, when
> a type is instantiated dynamically. This leads to two problems:
> 1. Abstract supertypes with implementation classes are attempted to be
> instantiated, which fails. (This problem can be worked around by not
> using abstract supertypes, but that shouldn't be actually called a
> workaround really!)
> 2. Setting (and also getting!) of features fails, when a dynamic class
> has multiple (implemented) supertypes.
This is an insurmountable problem. :-(
>
>
> If any of the problems 1 or 2 seem familar to you guys, i'd be really
> pleased to hear about your thoughts and recommendations.
Avoid 1 and don't do 2. Sorry, these are hard limitations.
>
> Best regards
> Janosch


Ed Merks
Professional Support: https://www.macromodeling.com/
icon14.gif  Re: Problems with dynamic AND generated EMF [message #518551 is a reply to message #517983] Thu, 04 March 2010 13:12 Go to previous message
Janos Kutscherauer is currently offline Janos KutscherauerFriend
Messages: 9
Registered: July 2009
Junior Member
Hi Ed,
Thanks so much for your explanations! Knowing the limitations surely helps working with them.
I can now sail around the problems by using generated implementation for both models.
Thanks for your help,
best regards
Janosch
Previous Topic:No model interfaces generated. Why?
Next Topic:[EMF Compare] NullPointerException in EMF Compare Merge Service
Goto Forum:
  


Current Time: Fri Mar 29 14:45:28 GMT 2024

Powered by FUDForum. Page generated in 0.02633 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top