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 |
Janos Kutscherauer 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 |
Ed Merks Messages: 33158 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/
|
|
| |
Goto Forum:
Current Time: Sat Jun 08 07:47:56 GMT 2024
Powered by FUDForum. Page generated in 0.03464 seconds
|