Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » The constructor BasicInternalEList<...> is undefined
The constructor BasicInternalEList<...> is undefined [message #1020944] Tue, 19 March 2013 08:34 Go to next message
Dirk Hoffmann is currently offline Dirk HoffmannFriend
Messages: 163
Registered: July 2009
Senior Member
Hi,

for a list type with nested type arguments the code generator produces
this code for the getter:

public List<AtomicFactory<Overlay<?>>> getOverlayFactories() {
if (overlayFactories == null) {
overlayFactories = new BasicInternalEList<AtomicFactory<Overlay<?>>>(
AtomicFactory.class);

}
return overlayFactories;
}

Unfortunately the compiler complains with "The constructor
BasicInternalEList<AtomicFactory<Overlay<?>>>(Class<AtomicFactory>) is
undefined"


What's the best way to cope with this situation?


I understand that having runtime type information about the component
type of the list is certainly an advantage. Java doesn't provide that
due to type erasure and the relation between <T> and Class<T> at least
ensures that the programmer provides the right runtime type. In this
case the code generator has to do it right.

Seems to be one of those Java Generics traps. Maybe it would be better
to just let the code generator provide the type without binding the type
argument to the Class<T> object, i.e. change the signature of the
constructor from

public BasicInternalEList(Class<? extends E> dataClass)

to

public BasicInternalEList(Class<?> dataClass)

BTW: Eclipse suggest a solution to the above compiler error which
indeeds compiles but only with the Eclipse compiler:

overlayFactories = new BasicInternalEList<AtomicFactory<Overlay<?>>>(
(Class<? extends AtomicFactory<Overlay<?>>>) AtomicFactory.class);

The javac compiler does not accept that solution, it says (package names
removed)

inconvertible types
found :
Class<AtomicFactory>
required:
Class<? extends AtomicFactory<Overlay<?>>>



Thanks and regards,
Dirk
Re: The constructor BasicInternalEList&lt;...&gt; is undefined [message #1021053 is a reply to message #1020944] Tue, 19 March 2013 12:45 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 26223
Registered: July 2009
Senior Member
Dirk,

Comments below.

On 19/03/2013 9:34 AM, Dirk Hoffmann wrote:
> Hi,
>
> for a list type with nested type arguments the code generator produces
> this code for the getter:
>
> public List<AtomicFactory<Overlay<?>>> getOverlayFactories() {
> if (overlayFactories == null) {
> overlayFactories = new
> BasicInternalEList<AtomicFactory<Overlay<?>>>(
> AtomicFactory.class);
>
> }
> return overlayFactories;
> }
>
> Unfortunately the compiler complains with "The constructor
> BasicInternalEList<AtomicFactory<Overlay<?>>>(Class<AtomicFactory>) is
> undefined"
You're using some special generator options to eliminate notifications?

I'm trying to imagine what you're model looked like that produced this.
Is an EDataType involved.
>
>
> What's the best way to cope with this situation?
>
>
> I understand that having runtime type information about the component
> type of the list is certainly an advantage. Java doesn't provide that
> due to type erasure and the relation between <T> and Class<T> at least
> ensures that the programmer provides the right runtime type. In this
> case the code generator has to do it right.
>
> Seems to be one of those Java Generics traps. Maybe it would be better
> to just let the code generator provide the type without binding the
> type argument to the Class<T> object, i.e. change the signature of the
> constructor from
Maybe, but I'd have to consider whether that breaks API for existing use
cases...
>
> public BasicInternalEList(Class<? extends E> dataClass)
>
> to
>
> public BasicInternalEList(Class<?> dataClass)
>
> BTW: Eclipse suggest a solution to the above compiler error which
> indeeds compiles but only with the Eclipse compiler:
>
> overlayFactories = new
> BasicInternalEList<AtomicFactory<Overlay<?>>>(
> (Class<? extends AtomicFactory<Overlay<?>>>)
> AtomicFactory.class);
>
> The javac compiler does not accept that solution, it says (package
> names removed)
>
> inconvertible types
> found :
> Class<AtomicFactory>
> required:
> Class<? extends AtomicFactory<Overlay<?>>>
Please open a bugzilla with a test case an I'll look more closely.
>
>
>
> Thanks and regards,
> Dirk
Re: The constructor BasicInternalEList&lt;...&gt; is undefined [message #1022623 is a reply to message #1021053] Fri, 22 March 2013 08:54 Go to previous messageGo to next message
Dirk Hoffmann is currently offline Dirk HoffmannFriend
Messages: 163
Registered: July 2009
Senior Member
Thanks for your fast reply and see below...

Am 19.03.2013 13:45, schrieb Ed Merks:
> Dirk,
>
> Comments below.
>
> On 19/03/2013 9:34 AM, Dirk Hoffmann wrote:
>> Hi,
>>
>> for a list type with nested type arguments the code generator produces
>> this code for the getter:
>>
>> public List<AtomicFactory<Overlay<?>>> getOverlayFactories() {
>> if (overlayFactories == null) {
>> overlayFactories = new
>> BasicInternalEList<AtomicFactory<Overlay<?>>>(
>> AtomicFactory.class);
>>
>> }
>> return overlayFactories;
>> }
>>
>> Unfortunately the compiler complains with "The constructor
>> BasicInternalEList<AtomicFactory<Overlay<?>>>(Class<AtomicFactory>) is
>> undefined"
> You're using some special generator options to eliminate notifications?
Yes, I do not need them.
>
> I'm trying to imagine what you're model looked like that produced this.
> Is an EDataType involved.

Well, for this project almost everything is modeled with EMF, not only
those classes whose instances are to be (de-)serialized to XMI.
(BTW: I wish I could change the defaults to transient="true" and
resolveProxies="false" when creating references with the Ecore Tools
Editor). One reason for EMF is the fact that it gives me a notion of
packages which I can ask for the classes it defines and that I can ask
references to types for their generic type arguments. That is not
possible with pure Java.

The method in question comes from an EClass called
"EmfBasedOverlaidAtomicFactory". It happens to have a type parameter "T"
which doesn't matter however. Its "overlayFactories" reference points to
the "AtomicFactory" EClass which also has a type parameter named "T".
The type argument to satisfy this type parameter is the "Overlay"
EClass. It also has a type parameter which is called "L". The type
argument for this one is left unspecified, the empty <eTypeArguments/>.
Removing the latter does not change the result.

How do you think about generics? Most of the time I love them but from
time to time the're almost driving me insane.

<eClassifiers xsi:type="ecore:EClass"
name="EmfBasedOverlaidAtomicFactory">
<eTypeParameters name="T"/>
<eStructuralFeatures xsi:type="ecore:EReference"
name="overlayFactories" upperBound="-1"
transient="true" containment="true" resolveProxies="false">
<eGenericType eClassifier="#//AtomicFactory">
<eTypeArguments eClassifier="#//Overlay">
<eTypeArguments/>
</eTypeArguments>
</eGenericType>
</eStructuralFeatures>
<eGenericSuperTypes eClassifier="#//AbstractEmfBasedAtomicFactory">
<eTypeArguments eTypeParameter="#//EmfBasedOverlaidAtomicFactory/T"/>
</eGenericSuperTypes>
</eClassifiers>

<eClassifiers xsi:type="ecore:EClass" name="AtomicFactory"
abstract="true" interface="true">
<eTypeParameters name="T"/>
<eOperations name="create">
<eGenericType eTypeParameter="#//AtomicFactory/T"/>
</eOperations>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="type"
changeable="false"
volatile="true" transient="true" derived="true">
<eGenericType eClassifier="ecore:EDataType
http://www.eclipse.org/emf/2002/Ecore#//EJavaClass">
<eTypeArguments eTypeParameter="#//AtomicFactory/T"/>
</eGenericType>
</eStructuralFeatures>
</eClassifiers>

<eClassifiers xsi:type="ecore:EClass" name="Overlay" abstract="true"
interface="true">
<eTypeParameters name="L"/>
<eOperations name="initialize"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="overlaid">
<eGenericType eTypeParameter="#//Overlay/L"/>
</eStructuralFeatures>
</eClassifiers>

>>
>>
>> What's the best way to cope with this situation?
>>
>>
>> I understand that having runtime type information about the component
>> type of the list is certainly an advantage. Java doesn't provide that
>> due to type erasure and the relation between <T> and Class<T> at least
>> ensures that the programmer provides the right runtime type. In this
>> case the code generator has to do it right.
>>
>> Seems to be one of those Java Generics traps. Maybe it would be better
>> to just let the code generator provide the type without binding the
>> type argument to the Class<T> object, i.e. change the signature of the
>> constructor from
> Maybe, but I'd have to consider whether that breaks API for existing use
> cases...
Couldn't you add that as an option to the genmodel?
>>
>> public BasicInternalEList(Class<? extends E> dataClass)
>>
>> to
>>
>> public BasicInternalEList(Class<?> dataClass)
>>
>> BTW: Eclipse suggest a solution to the above compiler error which
>> indeeds compiles but only with the Eclipse compiler:
>>
>> overlayFactories = new
>> BasicInternalEList<AtomicFactory<Overlay<?>>>(
>> (Class<? extends AtomicFactory<Overlay<?>>>)
>> AtomicFactory.class);
>>
>> The javac compiler does not accept that solution, it says (package
>> names removed)
>>
>> inconvertible types
>> found :
>> Class<AtomicFactory>
>> required:
>> Class<? extends AtomicFactory<Overlay<?>>>
> Please open a bugzilla with a test case an I'll look more closely.
Well, I never did this before, so it's gonna take some time.
>>
>>
>>
>> Thanks and regards,
>> Dirk
>
Regards,
Dirk
Re: The constructor BasicInternalEList&lt;...&gt; is undefined [message #1022998 is a reply to message #1022623] Sat, 23 March 2013 00:52 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 26223
Registered: July 2009
Senior Member
Dirk,

Comments below.

On 22/03/2013 9:54 AM, Dirk Hoffmann wrote:
> Thanks for your fast reply and see below...
>
> Am 19.03.2013 13:45, schrieb Ed Merks:
>> Dirk,
>>
>> Comments below.
>>
>> On 19/03/2013 9:34 AM, Dirk Hoffmann wrote:
>>> Hi,
>>>
>>> for a list type with nested type arguments the code generator produces
>>> this code for the getter:
>>>
>>> public List<AtomicFactory<Overlay<?>>> getOverlayFactories() {
>>> if (overlayFactories == null) {
>>> overlayFactories = new
>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(
>>> AtomicFactory.class);
>>>
>>> }
>>> return overlayFactories;
>>> }
>>>
>>> Unfortunately the compiler complains with "The constructor
>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(Class<AtomicFactory>) is
>>> undefined"
>> You're using some special generator options to eliminate notifications?
> Yes, I do not need them.
That may be, but your doing more than turning off notifications. You're
turning off containment too. Is that really what you want?
>>
>> I'm trying to imagine what you're model looked like that produced this.
>> Is an EDataType involved.
>
> Well, for this project almost everything is modeled with EMF, not only
> those classes whose instances are to be (de-)serialized to XMI.
> (BTW: I wish I could change the defaults to transient="true" and
> resolveProxies="false" when creating references with the Ecore Tools
> Editor). One reason for EMF is the fact that it gives me a notion of
> packages which I can ask for the classes it defines and that I can ask
> references to types for their generic type arguments. That is not
> possible with pure Java.
>
> The method in question comes from an EClass called
> "EmfBasedOverlaidAtomicFactory". It happens to have a type parameter
> "T" which doesn't matter however. Its "overlayFactories" reference
> points to the "AtomicFactory" EClass which also has a type parameter
> named "T". The type argument to satisfy this type parameter is the
> "Overlay" EClass. It also has a type parameter which is called "L".
> The type argument for this one is left unspecified, the empty
> <eTypeArguments/>. Removing the latter does not change the result.
>
> How do you think about generics? Most of the time I love them but from
> time to time the're almost driving me insane.
>
> <eClassifiers xsi:type="ecore:EClass"
> name="EmfBasedOverlaidAtomicFactory">
> <eTypeParameters name="T"/>
> <eStructuralFeatures xsi:type="ecore:EReference"
> name="overlayFactories" upperBound="-1"
> transient="true" containment="true" resolveProxies="false">
> <eGenericType eClassifier="#//AtomicFactory">
> <eTypeArguments eClassifier="#//Overlay">
> <eTypeArguments/>
> </eTypeArguments>
> </eGenericType>
> </eStructuralFeatures>
> <eGenericSuperTypes eClassifier="#//AbstractEmfBasedAtomicFactory">
> <eTypeArguments
> eTypeParameter="#//EmfBasedOverlaidAtomicFactory/T"/>
> </eGenericSuperTypes>
> </eClassifiers>
>
> <eClassifiers xsi:type="ecore:EClass" name="AtomicFactory"
> abstract="true" interface="true">
> <eTypeParameters name="T"/>
> <eOperations name="create">
> <eGenericType eTypeParameter="#//AtomicFactory/T"/>
> </eOperations>
> <eStructuralFeatures xsi:type="ecore:EAttribute" name="type"
> changeable="false"
> volatile="true" transient="true" derived="true">
> <eGenericType eClassifier="ecore:EDataType
> http://www.eclipse.org/emf/2002/Ecore#//EJavaClass">
> <eTypeArguments eTypeParameter="#//AtomicFactory/T"/>
> </eGenericType>
> </eStructuralFeatures>
> </eClassifiers>
>
> <eClassifiers xsi:type="ecore:EClass" name="Overlay" abstract="true"
> interface="true">
> <eTypeParameters name="L"/>
> <eOperations name="initialize"/>
> <eStructuralFeatures xsi:type="ecore:EAttribute" name="overlaid">
> <eGenericType eTypeParameter="#//Overlay/L"/>
> </eStructuralFeatures>
> </eClassifiers>
>
>>>
>>>
>>> What's the best way to cope with this situation?
>>>
>>>
>>> I understand that having runtime type information about the component
>>> type of the list is certainly an advantage. Java doesn't provide that
>>> due to type erasure and the relation between <T> and Class<T> at least
>>> ensures that the programmer provides the right runtime type. In this
>>> case the code generator has to do it right.
>>>
>>> Seems to be one of those Java Generics traps. Maybe it would be better
>>> to just let the code generator provide the type without binding the
>>> type argument to the Class<T> object, i.e. change the signature of the
>>> constructor from
>> Maybe, but I'd have to consider whether that breaks API for existing use
>> cases...
> Couldn't you add that as an option to the genmodel?
Changes the classes in the runtime is a different issue from changing
what's generated via the templates.
>>>
>>> public BasicInternalEList(Class<? extends E> dataClass)
>>>
>>> to
>>>
>>> public BasicInternalEList(Class<?> dataClass)
>>>
>>> BTW: Eclipse suggest a solution to the above compiler error which
>>> indeeds compiles but only with the Eclipse compiler:
>>>
>>> overlayFactories = new
>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(
>>> (Class<? extends AtomicFactory<Overlay<?>>>)
>>> AtomicFactory.class);
>>>
>>> The javac compiler does not accept that solution, it says (package
>>> names removed)
>>>
>>> inconvertible types
>>> found :
>>> Class<AtomicFactory>
>>> required:
>>> Class<? extends AtomicFactory<Overlay<?>>>
>> Please open a bugzilla with a test case an I'll look more closely.
> Well, I never did this before, so it's gonna take some time.
That's better than me spending the time trying to create a test case
from scratch or from snippets. :-P
>>>
>>>
>>>
>>> Thanks and regards,
>>> Dirk
>>
> Regards,
> Dirk
Re: The constructor BasicInternalEList&lt;...&gt; is undefined [message #1028539 is a reply to message #1022998] Thu, 28 March 2013 11:42 Go to previous messageGo to next message
Dirk Hoffmann is currently offline Dirk HoffmannFriend
Messages: 163
Registered: July 2009
Senior Member
Hi Ed,

see below...

Am 23.03.2013 01:52, schrieb Ed Merks:
> Dirk,
>
> Comments below.
>
> On 22/03/2013 9:54 AM, Dirk Hoffmann wrote:
>> Thanks for your fast reply and see below...
>>
>> Am 19.03.2013 13:45, schrieb Ed Merks:
>>> Dirk,
>>>
>>> Comments below.
>>>
>>> On 19/03/2013 9:34 AM, Dirk Hoffmann wrote:
>>>> Hi,
>>>>
>>>> for a list type with nested type arguments the code generator produces
>>>> this code for the getter:
>>>>
>>>> public List<AtomicFactory<Overlay<?>>> getOverlayFactories() {
>>>> if (overlayFactories == null) {
>>>> overlayFactories = new
>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(
>>>> AtomicFactory.class);
>>>>
>>>> }
>>>> return overlayFactories;
>>>> }
>>>>
>>>> Unfortunately the compiler complains with "The constructor
>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(Class<AtomicFactory>) is
>>>> undefined"
>>> You're using some special generator options to eliminate notifications?
>> Yes, I do not need them.
> That may be, but your doing more than turning off notifications. You're
> turning off containment too. Is that really what you want?
You mean eContainer() and eResource() returning null?
I noticed that but wasn't aware that it was due to the missing
notifications. Where I needed to get to the container I explicitly put
that into the model.
>>>
>>> I'm trying to imagine what you're model looked like that produced this.
>>> Is an EDataType involved.
>>
>> Well, for this project almost everything is modeled with EMF, not only
>> those classes whose instances are to be (de-)serialized to XMI.
>> (BTW: I wish I could change the defaults to transient="true" and
>> resolveProxies="false" when creating references with the Ecore Tools
>> Editor). One reason for EMF is the fact that it gives me a notion of
>> packages which I can ask for the classes it defines and that I can ask
>> references to types for their generic type arguments. That is not
>> possible with pure Java.
>>
>> The method in question comes from an EClass called
>> "EmfBasedOverlaidAtomicFactory". It happens to have a type parameter
>> "T" which doesn't matter however. Its "overlayFactories" reference
>> points to the "AtomicFactory" EClass which also has a type parameter
>> named "T". The type argument to satisfy this type parameter is the
>> "Overlay" EClass. It also has a type parameter which is called "L".
>> The type argument for this one is left unspecified, the empty
>> <eTypeArguments/>. Removing the latter does not change the result.
>>
>> How do you think about generics? Most of the time I love them but from
>> time to time the're almost driving me insane.
>>
>> <eClassifiers xsi:type="ecore:EClass"
>> name="EmfBasedOverlaidAtomicFactory">
>> <eTypeParameters name="T"/>
>> <eStructuralFeatures xsi:type="ecore:EReference"
>> name="overlayFactories" upperBound="-1"
>> transient="true" containment="true" resolveProxies="false">
>> <eGenericType eClassifier="#//AtomicFactory">
>> <eTypeArguments eClassifier="#//Overlay">
>> <eTypeArguments/>
>> </eTypeArguments>
>> </eGenericType>
>> </eStructuralFeatures>
>> <eGenericSuperTypes eClassifier="#//AbstractEmfBasedAtomicFactory">
>> <eTypeArguments
>> eTypeParameter="#//EmfBasedOverlaidAtomicFactory/T"/>
>> </eGenericSuperTypes>
>> </eClassifiers>
>>
>> <eClassifiers xsi:type="ecore:EClass" name="AtomicFactory"
>> abstract="true" interface="true">
>> <eTypeParameters name="T"/>
>> <eOperations name="create">
>> <eGenericType eTypeParameter="#//AtomicFactory/T"/>
>> </eOperations>
>> <eStructuralFeatures xsi:type="ecore:EAttribute" name="type"
>> changeable="false"
>> volatile="true" transient="true" derived="true">
>> <eGenericType eClassifier="ecore:EDataType
>> http://www.eclipse.org/emf/2002/Ecore#//EJavaClass">
>> <eTypeArguments eTypeParameter="#//AtomicFactory/T"/>
>> </eGenericType>
>> </eStructuralFeatures>
>> </eClassifiers>
>>
>> <eClassifiers xsi:type="ecore:EClass" name="Overlay" abstract="true"
>> interface="true">
>> <eTypeParameters name="L"/>
>> <eOperations name="initialize"/>
>> <eStructuralFeatures xsi:type="ecore:EAttribute" name="overlaid">
>> <eGenericType eTypeParameter="#//Overlay/L"/>
>> </eStructuralFeatures>
>> </eClassifiers>
>>
>>>>
>>>>
>>>> What's the best way to cope with this situation?
>>>>
>>>>
>>>> I understand that having runtime type information about the component
>>>> type of the list is certainly an advantage. Java doesn't provide that
>>>> due to type erasure and the relation between <T> and Class<T> at least
>>>> ensures that the programmer provides the right runtime type. In this
>>>> case the code generator has to do it right.
>>>>
>>>> Seems to be one of those Java Generics traps. Maybe it would be better
>>>> to just let the code generator provide the type without binding the
>>>> type argument to the Class<T> object, i.e. change the signature of the
>>>> constructor from
>>> Maybe, but I'd have to consider whether that breaks API for existing use
>>> cases...
>> Couldn't you add that as an option to the genmodel?
> Changes the classes in the runtime is a different issue from changing
> what's generated via the templates.
Ehm, sorry of course changing the constructor would affect the runtime.
The only thing you could do with the templates is to add some code to
work around the problem, i.e. a type cast to BasicInternalEList without
generic type arguments. Example:

@SuppressWarnings({ "unchecked", "rawtypes" })
public List<AtomicFactory<Overlay<?>>> getOverlayFactories() {
if (overlayFactories == null) {
overlayFactories = (BasicInternalEList) new
BasicInternalEList<AtomicFactory>(
AtomicFactory.class);
}
return overlayFactories;
}

>>>>
>>>> public BasicInternalEList(Class<? extends E> dataClass)
>>>>
>>>> to
>>>>
>>>> public BasicInternalEList(Class<?> dataClass)
>>>>
>>>> BTW: Eclipse suggest a solution to the above compiler error which
>>>> indeeds compiles but only with the Eclipse compiler:
>>>>
>>>> overlayFactories = new
>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(
>>>> (Class<? extends AtomicFactory<Overlay<?>>>)
>>>> AtomicFactory.class);
>>>>
>>>> The javac compiler does not accept that solution, it says (package
>>>> names removed)
>>>>
>>>> inconvertible types
>>>> found :
>>>> Class<AtomicFactory>
>>>> required:
>>>> Class<? extends AtomicFactory<Overlay<?>>>
>>> Please open a bugzilla with a test case an I'll look more closely.
>> Well, I never did this before, so it's gonna take some time.
> That's better than me spending the time trying to create a test case
> from scratch or from snippets. :-P
What about this:
I'll create the test case (I assume a minimal ecore model) and you make
it into a bugzilla call?

Regards,
Dirk
>>>>
>>>>
>>>>
>>>> Thanks and regards,
>>>> Dirk
>>>
>> Regards,
>> Dirk
>
Re: The constructor BasicInternalEList&lt;...&gt; is undefined [message #1028567 is a reply to message #1028539] Thu, 28 March 2013 12:39 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 26223
Registered: July 2009
Senior Member
Dirk,

Comments below.


On 28/03/2013 7:42 AM, Dirk Hoffmann wrote:
> Hi Ed,
>
> see below...
>
> Am 23.03.2013 01:52, schrieb Ed Merks:
>> Dirk,
>>
>> Comments below.
>>
>> On 22/03/2013 9:54 AM, Dirk Hoffmann wrote:
>>> Thanks for your fast reply and see below...
>>>
>>> Am 19.03.2013 13:45, schrieb Ed Merks:
>>>> Dirk,
>>>>
>>>> Comments below.
>>>>
>>>> On 19/03/2013 9:34 AM, Dirk Hoffmann wrote:
>>>>> Hi,
>>>>>
>>>>> for a list type with nested type arguments the code generator
>>>>> produces
>>>>> this code for the getter:
>>>>>
>>>>> public List<AtomicFactory<Overlay<?>>> getOverlayFactories() {
>>>>> if (overlayFactories == null) {
>>>>> overlayFactories = new
>>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(
>>>>> AtomicFactory.class);
>>>>>
>>>>> }
>>>>> return overlayFactories;
>>>>> }
>>>>>
>>>>> Unfortunately the compiler complains with "The constructor
>>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(Class<AtomicFactory>) is
>>>>>
>>>>> undefined"
>>>> You're using some special generator options to eliminate
>>>> notifications?
>>> Yes, I do not need them.
>> That may be, but your doing more than turning off notifications. You're
>> turning off containment too. Is that really what you want?
> You mean eContainer() and eResource() returning null?
> I noticed that but wasn't aware that it was due to the missing
> notifications. Where I needed to get to the container I explicitly put
> that into the model.
I don't think anything bidirectional will work. Even if you don't use
notifications, I think you're still better off to generate with them...
>>>>
>>>> I'm trying to imagine what you're model looked like that produced
>>>> this.
>>>> Is an EDataType involved.
>>>
>>> Well, for this project almost everything is modeled with EMF, not only
>>> those classes whose instances are to be (de-)serialized to XMI.
>>> (BTW: I wish I could change the defaults to transient="true" and
>>> resolveProxies="false" when creating references with the Ecore Tools
>>> Editor). One reason for EMF is the fact that it gives me a notion of
>>> packages which I can ask for the classes it defines and that I can ask
>>> references to types for their generic type arguments. That is not
>>> possible with pure Java.
>>>
>>> The method in question comes from an EClass called
>>> "EmfBasedOverlaidAtomicFactory". It happens to have a type parameter
>>> "T" which doesn't matter however. Its "overlayFactories" reference
>>> points to the "AtomicFactory" EClass which also has a type parameter
>>> named "T". The type argument to satisfy this type parameter is the
>>> "Overlay" EClass. It also has a type parameter which is called "L".
>>> The type argument for this one is left unspecified, the empty
>>> <eTypeArguments/>. Removing the latter does not change the result.
>>>
>>> How do you think about generics? Most of the time I love them but from
>>> time to time the're almost driving me insane.
>>>
>>> <eClassifiers xsi:type="ecore:EClass"
>>> name="EmfBasedOverlaidAtomicFactory">
>>> <eTypeParameters name="T"/>
>>> <eStructuralFeatures xsi:type="ecore:EReference"
>>> name="overlayFactories" upperBound="-1"
>>> transient="true" containment="true" resolveProxies="false">
>>> <eGenericType eClassifier="#//AtomicFactory">
>>> <eTypeArguments eClassifier="#//Overlay">
>>> <eTypeArguments/>
>>> </eTypeArguments>
>>> </eGenericType>
>>> </eStructuralFeatures>
>>> <eGenericSuperTypes eClassifier="#//AbstractEmfBasedAtomicFactory">
>>> <eTypeArguments
>>> eTypeParameter="#//EmfBasedOverlaidAtomicFactory/T"/>
>>> </eGenericSuperTypes>
>>> </eClassifiers>
>>>
>>> <eClassifiers xsi:type="ecore:EClass" name="AtomicFactory"
>>> abstract="true" interface="true">
>>> <eTypeParameters name="T"/>
>>> <eOperations name="create">
>>> <eGenericType eTypeParameter="#//AtomicFactory/T"/>
>>> </eOperations>
>>> <eStructuralFeatures xsi:type="ecore:EAttribute" name="type"
>>> changeable="false"
>>> volatile="true" transient="true" derived="true">
>>> <eGenericType eClassifier="ecore:EDataType
>>> http://www.eclipse.org/emf/2002/Ecore#//EJavaClass">
>>> <eTypeArguments eTypeParameter="#//AtomicFactory/T"/>
>>> </eGenericType>
>>> </eStructuralFeatures>
>>> </eClassifiers>
>>>
>>> <eClassifiers xsi:type="ecore:EClass" name="Overlay" abstract="true"
>>> interface="true">
>>> <eTypeParameters name="L"/>
>>> <eOperations name="initialize"/>
>>> <eStructuralFeatures xsi:type="ecore:EAttribute" name="overlaid">
>>> <eGenericType eTypeParameter="#//Overlay/L"/>
>>> </eStructuralFeatures>
>>> </eClassifiers>
>>>
>>>>>
>>>>>
>>>>> What's the best way to cope with this situation?
>>>>>
>>>>>
>>>>> I understand that having runtime type information about the component
>>>>> type of the list is certainly an advantage. Java doesn't provide that
>>>>> due to type erasure and the relation between <T> and Class<T> at
>>>>> least
>>>>> ensures that the programmer provides the right runtime type. In this
>>>>> case the code generator has to do it right.
>>>>>
>>>>> Seems to be one of those Java Generics traps. Maybe it would be
>>>>> better
>>>>> to just let the code generator provide the type without binding the
>>>>> type argument to the Class<T> object, i.e. change the signature of
>>>>> the
>>>>> constructor from
>>>> Maybe, but I'd have to consider whether that breaks API for
>>>> existing use
>>>> cases...
>>> Couldn't you add that as an option to the genmodel?
>> Changes the classes in the runtime is a different issue from changing
>> what's generated via the templates.
> Ehm, sorry of course changing the constructor would affect the
> runtime. The only thing you could do with the templates is to add some
> code to work around the problem, i.e. a type cast to
> BasicInternalEList without generic type arguments. Example:
>
> @SuppressWarnings({ "unchecked", "rawtypes" })
> public List<AtomicFactory<Overlay<?>>> getOverlayFactories() {
> if (overlayFactories == null) {
> overlayFactories = (BasicInternalEList) new
> BasicInternalEList<AtomicFactory>(
> AtomicFactory.class);
> }
> return overlayFactories;
> }
>
>>>>>
>>>>> public BasicInternalEList(Class<? extends E> dataClass)
>>>>>
>>>>> to
>>>>>
>>>>> public BasicInternalEList(Class<?> dataClass)
>>>>>
>>>>> BTW: Eclipse suggest a solution to the above compiler error which
>>>>> indeeds compiles but only with the Eclipse compiler:
>>>>>
>>>>> overlayFactories = new
>>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(
>>>>> (Class<? extends AtomicFactory<Overlay<?>>>)
>>>>> AtomicFactory.class);
>>>>>
>>>>> The javac compiler does not accept that solution, it says (package
>>>>> names removed)
>>>>>
>>>>> inconvertible types
>>>>> found :
>>>>> Class<AtomicFactory>
>>>>> required:
>>>>> Class<? extends AtomicFactory<Overlay<?>>>
>>>> Please open a bugzilla with a test case an I'll look more closely.
>>> Well, I never did this before, so it's gonna take some time.
>> That's better than me spending the time trying to create a test case
>> from scratch or from snippets. :-P
> What about this:
> I'll create the test case (I assume a minimal ecore model) and you
> make it into a bugzilla call?
Yes, I'll have a look. It should work properly, but I don't think it's
a good pattern to use...
>
> Regards,
> Dirk
>>>>>
>>>>>
>>>>>
>>>>> Thanks and regards,
>>>>> Dirk
>>>>
>>> Regards,
>>> Dirk
>>
>
Re: The constructor BasicInternalEList&lt;...&gt; is undefined [message #1028633 is a reply to message #1028567] Thu, 28 March 2013 14:35 Go to previous messageGo to next message
Dirk Hoffmann is currently offline Dirk HoffmannFriend
Messages: 163
Registered: July 2009
Senior Member
Hi Ed,

find attached a minimum meta model + genmodel causing the compilation issue.

Interestingly other EMF list implementations do not have that problem.
They expect Class<?> as opposed to Class<? extends E> in their
constructors. Another EList implementation could solve the problem.

More below...

Am 28.03.2013 13:39, schrieb Ed Merks:
> Dirk,
>
> Comments below.
>
>
> On 28/03/2013 7:42 AM, Dirk Hoffmann wrote:
>> Hi Ed,
>>
>> see below...
>>
>> Am 23.03.2013 01:52, schrieb Ed Merks:
>>> Dirk,
>>>
>>> Comments below.
>>>
>>> On 22/03/2013 9:54 AM, Dirk Hoffmann wrote:
>>>> Thanks for your fast reply and see below...
>>>>
>>>> Am 19.03.2013 13:45, schrieb Ed Merks:
>>>>> Dirk,
>>>>>
>>>>> Comments below.
>>>>>
>>>>> On 19/03/2013 9:34 AM, Dirk Hoffmann wrote:
>>>>>> Hi,
>>>>>>
>>>>>> for a list type with nested type arguments the code generator
>>>>>> produces
>>>>>> this code for the getter:
>>>>>>
>>>>>> public List<AtomicFactory<Overlay<?>>> getOverlayFactories() {
>>>>>> if (overlayFactories == null) {
>>>>>> overlayFactories = new
>>>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(
>>>>>> AtomicFactory.class);
>>>>>>
>>>>>> }
>>>>>> return overlayFactories;
>>>>>> }
>>>>>>
>>>>>> Unfortunately the compiler complains with "The constructor
>>>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(Class<AtomicFactory>) is
>>>>>>
>>>>>> undefined"
>>>>> You're using some special generator options to eliminate
>>>>> notifications?
>>>> Yes, I do not need them.
>>> That may be, but your doing more than turning off notifications. You're
>>> turning off containment too. Is that really what you want?
>> You mean eContainer() and eResource() returning null?
>> I noticed that but wasn't aware that it was due to the missing
>> notifications. Where I needed to get to the container I explicitly put
>> that into the model.
> I don't think anything bidirectional will work. Even if you don't use
> notifications, I think you're still better off to generate with them...
Well, for this project I do a lot with EMF and its a bit of an
experiment on how far I can get with EMF beyond just representing pure
model. It uses 12 Ecore models and genmodels which depend on each other.
The genmodels are different depending on what the models are for. There
are a lot of classes that do not represent "model" in the sense of MVC.
For example there are classes whose names end in "CompositeBuilder" and
which contain code to create SWT and Jface elements. The whole software
is modeled, not just the data part. And because of that I wanted to
minimize the memory footprint to the lowest possible. Along these lines
EObjectImpl has been replaced by a class without any member variables,
cutting off a lot of EMF functionality (like containment and
bidirectionality) of course. Beside producing cleaner code together with
diagrams that visualize the code an advantage of using EMF in my context
is that the runtime meta data gives me information about which classes
are in a package and about which type parameters a class has, something
not provided by Java reflection. The first is needed because most
objects are created through an abstract factory which uses the EFactory
instances. The reason is that there are variations of our product and a
particular variant gets activated by choosing a particular EFactory
creating specializations of general classes or interfaces. Its really
cool to see it working. Sorry for boring you all with so much text.
>>>>>
>>>>> I'm trying to imagine what you're model looked like that produced
>>>>> this.
>>>>> Is an EDataType involved.
>>>>
>>>> Well, for this project almost everything is modeled with EMF, not only
>>>> those classes whose instances are to be (de-)serialized to XMI.
>>>> (BTW: I wish I could change the defaults to transient="true" and
>>>> resolveProxies="false" when creating references with the Ecore Tools
>>>> Editor). One reason for EMF is the fact that it gives me a notion of
>>>> packages which I can ask for the classes it defines and that I can ask
>>>> references to types for their generic type arguments. That is not
>>>> possible with pure Java.
>>>>
>>>> The method in question comes from an EClass called
>>>> "EmfBasedOverlaidAtomicFactory". It happens to have a type parameter
>>>> "T" which doesn't matter however. Its "overlayFactories" reference
>>>> points to the "AtomicFactory" EClass which also has a type parameter
>>>> named "T". The type argument to satisfy this type parameter is the
>>>> "Overlay" EClass. It also has a type parameter which is called "L".
>>>> The type argument for this one is left unspecified, the empty
>>>> <eTypeArguments/>. Removing the latter does not change the result.
>>>>
>>>> How do you think about generics? Most of the time I love them but from
>>>> time to time the're almost driving me insane.
>>>>
>>>> <eClassifiers xsi:type="ecore:EClass"
>>>> name="EmfBasedOverlaidAtomicFactory">
>>>> <eTypeParameters name="T"/>
>>>> <eStructuralFeatures xsi:type="ecore:EReference"
>>>> name="overlayFactories" upperBound="-1"
>>>> transient="true" containment="true" resolveProxies="false">
>>>> <eGenericType eClassifier="#//AtomicFactory">
>>>> <eTypeArguments eClassifier="#//Overlay">
>>>> <eTypeArguments/>
>>>> </eTypeArguments>
>>>> </eGenericType>
>>>> </eStructuralFeatures>
>>>> <eGenericSuperTypes eClassifier="#//AbstractEmfBasedAtomicFactory">
>>>> <eTypeArguments
>>>> eTypeParameter="#//EmfBasedOverlaidAtomicFactory/T"/>
>>>> </eGenericSuperTypes>
>>>> </eClassifiers>
>>>>
>>>> <eClassifiers xsi:type="ecore:EClass" name="AtomicFactory"
>>>> abstract="true" interface="true">
>>>> <eTypeParameters name="T"/>
>>>> <eOperations name="create">
>>>> <eGenericType eTypeParameter="#//AtomicFactory/T"/>
>>>> </eOperations>
>>>> <eStructuralFeatures xsi:type="ecore:EAttribute" name="type"
>>>> changeable="false"
>>>> volatile="true" transient="true" derived="true">
>>>> <eGenericType eClassifier="ecore:EDataType
>>>> http://www.eclipse.org/emf/2002/Ecore#//EJavaClass">
>>>> <eTypeArguments eTypeParameter="#//AtomicFactory/T"/>
>>>> </eGenericType>
>>>> </eStructuralFeatures>
>>>> </eClassifiers>
>>>>
>>>> <eClassifiers xsi:type="ecore:EClass" name="Overlay" abstract="true"
>>>> interface="true">
>>>> <eTypeParameters name="L"/>
>>>> <eOperations name="initialize"/>
>>>> <eStructuralFeatures xsi:type="ecore:EAttribute" name="overlaid">
>>>> <eGenericType eTypeParameter="#//Overlay/L"/>
>>>> </eStructuralFeatures>
>>>> </eClassifiers>
>>>>
>>>>>>
>>>>>>
>>>>>> What's the best way to cope with this situation?
>>>>>>
>>>>>>
>>>>>> I understand that having runtime type information about the component
>>>>>> type of the list is certainly an advantage. Java doesn't provide that
>>>>>> due to type erasure and the relation between <T> and Class<T> at
>>>>>> least
>>>>>> ensures that the programmer provides the right runtime type. In this
>>>>>> case the code generator has to do it right.
>>>>>>
>>>>>> Seems to be one of those Java Generics traps. Maybe it would be
>>>>>> better
>>>>>> to just let the code generator provide the type without binding the
>>>>>> type argument to the Class<T> object, i.e. change the signature of
>>>>>> the
>>>>>> constructor from
>>>>> Maybe, but I'd have to consider whether that breaks API for
>>>>> existing use
>>>>> cases...
>>>> Couldn't you add that as an option to the genmodel?
>>> Changes the classes in the runtime is a different issue from changing
>>> what's generated via the templates.
>> Ehm, sorry of course changing the constructor would affect the
>> runtime. The only thing you could do with the templates is to add some
>> code to work around the problem, i.e. a type cast to
>> BasicInternalEList without generic type arguments. Example:
>>
>> @SuppressWarnings({ "unchecked", "rawtypes" })
>> public List<AtomicFactory<Overlay<?>>> getOverlayFactories() {
>> if (overlayFactories == null) {
>> overlayFactories = (BasicInternalEList) new
>> BasicInternalEList<AtomicFactory>(
>> AtomicFactory.class);
>> }
>> return overlayFactories;
>> }
>>
>>>>>>
>>>>>> public BasicInternalEList(Class<? extends E> dataClass)
>>>>>>
>>>>>> to
>>>>>>
>>>>>> public BasicInternalEList(Class<?> dataClass)
>>>>>>
>>>>>> BTW: Eclipse suggest a solution to the above compiler error which
>>>>>> indeeds compiles but only with the Eclipse compiler:
>>>>>>
>>>>>> overlayFactories = new
>>>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(
>>>>>> (Class<? extends AtomicFactory<Overlay<?>>>)
>>>>>> AtomicFactory.class);
>>>>>>
>>>>>> The javac compiler does not accept that solution, it says (package
>>>>>> names removed)
>>>>>>
>>>>>> inconvertible types
>>>>>> found :
>>>>>> Class<AtomicFactory>
>>>>>> required:
>>>>>> Class<? extends AtomicFactory<Overlay<?>>>
>>>>> Please open a bugzilla with a test case an I'll look more closely.
>>>> Well, I never did this before, so it's gonna take some time.
>>> That's better than me spending the time trying to create a test case
>>> from scratch or from snippets. :-P
>> What about this:
>> I'll create the test case (I assume a minimal ecore model) and you
>> make it into a bugzilla call?
> Yes, I'll have a look. It should work properly, but I don't think it's
> a good pattern to use...
It's a nasty workaround and fixing it in the runtime is definitely the
cleaner way. If you don not want to change the BasicInternalEList
constructors in the runtime what about adding an improved version of
BasicInternalEList to the runtime and changing the templates to use the
new implementation if switched on in the genmodel.

Regards,
Dirk
>>
>> Regards,
>> Dirk
>>>>>>
>>>>>>
>>>>>>
>>>>>> Thanks and regards,
>>>>>> Dirk
>>>>>
>>>> Regards,
>>>> Dirk
>>>
>>
>
Re: The constructor BasicInternalEList&lt;...&gt; is undefined [message #1028761 is a reply to message #1028633] Thu, 28 March 2013 17:49 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 26223
Registered: July 2009
Senior Member
Dirk,

Please open it as a bugzilla so there's a tracking reference for any
changes I make. I think widening the signature of the constructor
arguments wouldn't cause any problems, though changing it for the field
could be... But we could always do an unchecked cast for that... I
won't have time to look until I'm back from EclipseCon next week...


On 28/03/2013 10:35 AM, Dirk Hoffmann wrote:
> Hi Ed,
>
> find attached a minimum meta model + genmodel causing the compilation
> issue.
>
> Interestingly other EMF list implementations do not have that problem.
> They expect Class<?> as opposed to Class<? extends E> in their
> constructors. Another EList implementation could solve the problem.
>
> More below...
>
> Am 28.03.2013 13:39, schrieb Ed Merks:
>> Dirk,
>>
>> Comments below.
>>
>>
>> On 28/03/2013 7:42 AM, Dirk Hoffmann wrote:
>>> Hi Ed,
>>>
>>> see below...
>>>
>>> Am 23.03.2013 01:52, schrieb Ed Merks:
>>>> Dirk,
>>>>
>>>> Comments below.
>>>>
>>>> On 22/03/2013 9:54 AM, Dirk Hoffmann wrote:
>>>>> Thanks for your fast reply and see below...
>>>>>
>>>>> Am 19.03.2013 13:45, schrieb Ed Merks:
>>>>>> Dirk,
>>>>>>
>>>>>> Comments below.
>>>>>>
>>>>>> On 19/03/2013 9:34 AM, Dirk Hoffmann wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> for a list type with nested type arguments the code generator
>>>>>>> produces
>>>>>>> this code for the getter:
>>>>>>>
>>>>>>> public List<AtomicFactory<Overlay<?>>> getOverlayFactories() {
>>>>>>> if (overlayFactories == null) {
>>>>>>> overlayFactories = new
>>>>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(
>>>>>>> AtomicFactory.class);
>>>>>>>
>>>>>>> }
>>>>>>> return overlayFactories;
>>>>>>> }
>>>>>>>
>>>>>>> Unfortunately the compiler complains with "The constructor
>>>>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(Class<AtomicFactory>)
>>>>>>> is
>>>>>>>
>>>>>>> undefined"
>>>>>> You're using some special generator options to eliminate
>>>>>> notifications?
>>>>> Yes, I do not need them.
>>>> That may be, but your doing more than turning off notifications.
>>>> You're
>>>> turning off containment too. Is that really what you want?
>>> You mean eContainer() and eResource() returning null?
>>> I noticed that but wasn't aware that it was due to the missing
>>> notifications. Where I needed to get to the container I explicitly put
>>> that into the model.
>> I don't think anything bidirectional will work. Even if you don't use
>> notifications, I think you're still better off to generate with them...
> Well, for this project I do a lot with EMF and its a bit of an
> experiment on how far I can get with EMF beyond just representing pure
> model. It uses 12 Ecore models and genmodels which depend on each
> other. The genmodels are different depending on what the models are
> for. There are a lot of classes that do not represent "model" in the
> sense of MVC. For example there are classes whose names end in
> "CompositeBuilder" and which contain code to create SWT and Jface
> elements. The whole software is modeled, not just the data part. And
> because of that I wanted to minimize the memory footprint to the
> lowest possible. Along these lines EObjectImpl has been replaced by a
> class without any member variables, cutting off a lot of EMF
> functionality (like containment and bidirectionality) of course.
> Beside producing cleaner code together with diagrams that visualize
> the code an advantage of using EMF in my context is that the runtime
> meta data gives me information about which classes are in a package
> and about which type parameters a class has, something not provided by
> Java reflection. The first is needed because most objects are created
> through an abstract factory which uses the EFactory instances. The
> reason is that there are variations of our product and a particular
> variant gets activated by choosing a particular EFactory creating
> specializations of general classes or interfaces. Its really cool to
> see it working. Sorry for boring you all with so much text.
>>>>>>
>>>>>> I'm trying to imagine what you're model looked like that produced
>>>>>> this.
>>>>>> Is an EDataType involved.
>>>>>
>>>>> Well, for this project almost everything is modeled with EMF, not
>>>>> only
>>>>> those classes whose instances are to be (de-)serialized to XMI.
>>>>> (BTW: I wish I could change the defaults to transient="true" and
>>>>> resolveProxies="false" when creating references with the Ecore Tools
>>>>> Editor). One reason for EMF is the fact that it gives me a notion of
>>>>> packages which I can ask for the classes it defines and that I can
>>>>> ask
>>>>> references to types for their generic type arguments. That is not
>>>>> possible with pure Java.
>>>>>
>>>>> The method in question comes from an EClass called
>>>>> "EmfBasedOverlaidAtomicFactory". It happens to have a type parameter
>>>>> "T" which doesn't matter however. Its "overlayFactories" reference
>>>>> points to the "AtomicFactory" EClass which also has a type parameter
>>>>> named "T". The type argument to satisfy this type parameter is the
>>>>> "Overlay" EClass. It also has a type parameter which is called "L".
>>>>> The type argument for this one is left unspecified, the empty
>>>>> <eTypeArguments/>. Removing the latter does not change the result.
>>>>>
>>>>> How do you think about generics? Most of the time I love them but
>>>>> from
>>>>> time to time the're almost driving me insane.
>>>>>
>>>>> <eClassifiers xsi:type="ecore:EClass"
>>>>> name="EmfBasedOverlaidAtomicFactory">
>>>>> <eTypeParameters name="T"/>
>>>>> <eStructuralFeatures xsi:type="ecore:EReference"
>>>>> name="overlayFactories" upperBound="-1"
>>>>> transient="true" containment="true" resolveProxies="false">
>>>>> <eGenericType eClassifier="#//AtomicFactory">
>>>>> <eTypeArguments eClassifier="#//Overlay">
>>>>> <eTypeArguments/>
>>>>> </eTypeArguments>
>>>>> </eGenericType>
>>>>> </eStructuralFeatures>
>>>>> <eGenericSuperTypes
>>>>> eClassifier="#//AbstractEmfBasedAtomicFactory">
>>>>> <eTypeArguments
>>>>> eTypeParameter="#//EmfBasedOverlaidAtomicFactory/T"/>
>>>>> </eGenericSuperTypes>
>>>>> </eClassifiers>
>>>>>
>>>>> <eClassifiers xsi:type="ecore:EClass" name="AtomicFactory"
>>>>> abstract="true" interface="true">
>>>>> <eTypeParameters name="T"/>
>>>>> <eOperations name="create">
>>>>> <eGenericType eTypeParameter="#//AtomicFactory/T"/>
>>>>> </eOperations>
>>>>> <eStructuralFeatures xsi:type="ecore:EAttribute" name="type"
>>>>> changeable="false"
>>>>> volatile="true" transient="true" derived="true">
>>>>> <eGenericType eClassifier="ecore:EDataType
>>>>> http://www.eclipse.org/emf/2002/Ecore#//EJavaClass">
>>>>> <eTypeArguments eTypeParameter="#//AtomicFactory/T"/>
>>>>> </eGenericType>
>>>>> </eStructuralFeatures>
>>>>> </eClassifiers>
>>>>>
>>>>> <eClassifiers xsi:type="ecore:EClass" name="Overlay"
>>>>> abstract="true"
>>>>> interface="true">
>>>>> <eTypeParameters name="L"/>
>>>>> <eOperations name="initialize"/>
>>>>> <eStructuralFeatures xsi:type="ecore:EAttribute" name="overlaid">
>>>>> <eGenericType eTypeParameter="#//Overlay/L"/>
>>>>> </eStructuralFeatures>
>>>>> </eClassifiers>
>>>>>
>>>>>>>
>>>>>>>
>>>>>>> What's the best way to cope with this situation?
>>>>>>>
>>>>>>>
>>>>>>> I understand that having runtime type information about the
>>>>>>> component
>>>>>>> type of the list is certainly an advantage. Java doesn't provide
>>>>>>> that
>>>>>>> due to type erasure and the relation between <T> and Class<T> at
>>>>>>> least
>>>>>>> ensures that the programmer provides the right runtime type. In
>>>>>>> this
>>>>>>> case the code generator has to do it right.
>>>>>>>
>>>>>>> Seems to be one of those Java Generics traps. Maybe it would be
>>>>>>> better
>>>>>>> to just let the code generator provide the type without binding the
>>>>>>> type argument to the Class<T> object, i.e. change the signature of
>>>>>>> the
>>>>>>> constructor from
>>>>>> Maybe, but I'd have to consider whether that breaks API for
>>>>>> existing use
>>>>>> cases...
>>>>> Couldn't you add that as an option to the genmodel?
>>>> Changes the classes in the runtime is a different issue from changing
>>>> what's generated via the templates.
>>> Ehm, sorry of course changing the constructor would affect the
>>> runtime. The only thing you could do with the templates is to add some
>>> code to work around the problem, i.e. a type cast to
>>> BasicInternalEList without generic type arguments. Example:
>>>
>>> @SuppressWarnings({ "unchecked", "rawtypes" })
>>> public List<AtomicFactory<Overlay<?>>> getOverlayFactories() {
>>> if (overlayFactories == null) {
>>> overlayFactories = (BasicInternalEList) new
>>> BasicInternalEList<AtomicFactory>(
>>> AtomicFactory.class);
>>> }
>>> return overlayFactories;
>>> }
>>>
>>>>>>>
>>>>>>> public BasicInternalEList(Class<? extends E> dataClass)
>>>>>>>
>>>>>>> to
>>>>>>>
>>>>>>> public BasicInternalEList(Class<?> dataClass)
>>>>>>>
>>>>>>> BTW: Eclipse suggest a solution to the above compiler error which
>>>>>>> indeeds compiles but only with the Eclipse compiler:
>>>>>>>
>>>>>>> overlayFactories = new
>>>>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(
>>>>>>> (Class<? extends AtomicFactory<Overlay<?>>>)
>>>>>>> AtomicFactory.class);
>>>>>>>
>>>>>>> The javac compiler does not accept that solution, it says (package
>>>>>>> names removed)
>>>>>>>
>>>>>>> inconvertible types
>>>>>>> found :
>>>>>>> Class<AtomicFactory>
>>>>>>> required:
>>>>>>> Class<? extends AtomicFactory<Overlay<?>>>
>>>>>> Please open a bugzilla with a test case an I'll look more closely.
>>>>> Well, I never did this before, so it's gonna take some time.
>>>> That's better than me spending the time trying to create a test case
>>>> from scratch or from snippets. :-P
>>> What about this:
>>> I'll create the test case (I assume a minimal ecore model) and you
>>> make it into a bugzilla call?
>> Yes, I'll have a look. It should work properly, but I don't think it's
>> a good pattern to use...
> It's a nasty workaround and fixing it in the runtime is definitely the
> cleaner way. If you don not want to change the BasicInternalEList
> constructors in the runtime what about adding an improved version of
> BasicInternalEList to the runtime and changing the templates to use
> the new implementation if switched on in the genmodel.
>
> Regards,
> Dirk
>>>
>>> Regards,
>>> Dirk
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Thanks and regards,
>>>>>>> Dirk
>>>>>>
>>>>> Regards,
>>>>> Dirk
>>>>
>>>
>>
>
Re: The constructor BasicInternalEList&lt;...&gt; is undefined [message #1031207 is a reply to message #1028633] Mon, 01 April 2013 11:05 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 26223
Registered: July 2009
Senior Member
Dirk,

I opened https://bugs.eclipse.org/bugs/show_bug.cgi?id=404661 and
committed the changes. It seemed best simply to remove the bounds from
both the arguments and the field. The changes are binary compatible but
not necessarily source compatible, though I doubt anyone will be
impacted by the change even in their source.

On 28/03/2013 3:35 PM, Dirk Hoffmann wrote:
> Hi Ed,
>
> find attached a minimum meta model + genmodel causing the compilation
> issue.
>
> Interestingly other EMF list implementations do not have that problem.
> They expect Class<?> as opposed to Class<? extends E> in their
> constructors. Another EList implementation could solve the problem.
>
> More below...
>
> Am 28.03.2013 13:39, schrieb Ed Merks:
>> Dirk,
>>
>> Comments below.
>>
>>
>> On 28/03/2013 7:42 AM, Dirk Hoffmann wrote:
>>> Hi Ed,
>>>
>>> see below...
>>>
>>> Am 23.03.2013 01:52, schrieb Ed Merks:
>>>> Dirk,
>>>>
>>>> Comments below.
>>>>
>>>> On 22/03/2013 9:54 AM, Dirk Hoffmann wrote:
>>>>> Thanks for your fast reply and see below...
>>>>>
>>>>> Am 19.03.2013 13:45, schrieb Ed Merks:
>>>>>> Dirk,
>>>>>>
>>>>>> Comments below.
>>>>>>
>>>>>> On 19/03/2013 9:34 AM, Dirk Hoffmann wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> for a list type with nested type arguments the code generator
>>>>>>> produces
>>>>>>> this code for the getter:
>>>>>>>
>>>>>>> public List<AtomicFactory<Overlay<?>>> getOverlayFactories() {
>>>>>>> if (overlayFactories == null) {
>>>>>>> overlayFactories = new
>>>>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(
>>>>>>> AtomicFactory.class);
>>>>>>>
>>>>>>> }
>>>>>>> return overlayFactories;
>>>>>>> }
>>>>>>>
>>>>>>> Unfortunately the compiler complains with "The constructor
>>>>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(Class<AtomicFactory>)
>>>>>>> is
>>>>>>>
>>>>>>> undefined"
>>>>>> You're using some special generator options to eliminate
>>>>>> notifications?
>>>>> Yes, I do not need them.
>>>> That may be, but your doing more than turning off notifications.
>>>> You're
>>>> turning off containment too. Is that really what you want?
>>> You mean eContainer() and eResource() returning null?
>>> I noticed that but wasn't aware that it was due to the missing
>>> notifications. Where I needed to get to the container I explicitly put
>>> that into the model.
>> I don't think anything bidirectional will work. Even if you don't use
>> notifications, I think you're still better off to generate with them...
> Well, for this project I do a lot with EMF and its a bit of an
> experiment on how far I can get with EMF beyond just representing pure
> model. It uses 12 Ecore models and genmodels which depend on each
> other. The genmodels are different depending on what the models are
> for. There are a lot of classes that do not represent "model" in the
> sense of MVC. For example there are classes whose names end in
> "CompositeBuilder" and which contain code to create SWT and Jface
> elements. The whole software is modeled, not just the data part. And
> because of that I wanted to minimize the memory footprint to the
> lowest possible. Along these lines EObjectImpl has been replaced by a
> class without any member variables, cutting off a lot of EMF
> functionality (like containment and bidirectionality) of course.
> Beside producing cleaner code together with diagrams that visualize
> the code an advantage of using EMF in my context is that the runtime
> meta data gives me information about which classes are in a package
> and about which type parameters a class has, something not provided by
> Java reflection. The first is needed because most objects are created
> through an abstract factory which uses the EFactory instances. The
> reason is that there are variations of our product and a particular
> variant gets activated by choosing a particular EFactory creating
> specializations of general classes or interfaces. Its really cool to
> see it working. Sorry for boring you all with so much text.
>>>>>>
>>>>>> I'm trying to imagine what you're model looked like that produced
>>>>>> this.
>>>>>> Is an EDataType involved.
>>>>>
>>>>> Well, for this project almost everything is modeled with EMF, not
>>>>> only
>>>>> those classes whose instances are to be (de-)serialized to XMI.
>>>>> (BTW: I wish I could change the defaults to transient="true" and
>>>>> resolveProxies="false" when creating references with the Ecore Tools
>>>>> Editor). One reason for EMF is the fact that it gives me a notion of
>>>>> packages which I can ask for the classes it defines and that I can
>>>>> ask
>>>>> references to types for their generic type arguments. That is not
>>>>> possible with pure Java.
>>>>>
>>>>> The method in question comes from an EClass called
>>>>> "EmfBasedOverlaidAtomicFactory". It happens to have a type parameter
>>>>> "T" which doesn't matter however. Its "overlayFactories" reference
>>>>> points to the "AtomicFactory" EClass which also has a type parameter
>>>>> named "T". The type argument to satisfy this type parameter is the
>>>>> "Overlay" EClass. It also has a type parameter which is called "L".
>>>>> The type argument for this one is left unspecified, the empty
>>>>> <eTypeArguments/>. Removing the latter does not change the result.
>>>>>
>>>>> How do you think about generics? Most of the time I love them but
>>>>> from
>>>>> time to time the're almost driving me insane.
>>>>>
>>>>> <eClassifiers xsi:type="ecore:EClass"
>>>>> name="EmfBasedOverlaidAtomicFactory">
>>>>> <eTypeParameters name="T"/>
>>>>> <eStructuralFeatures xsi:type="ecore:EReference"
>>>>> name="overlayFactories" upperBound="-1"
>>>>> transient="true" containment="true" resolveProxies="false">
>>>>> <eGenericType eClassifier="#//AtomicFactory">
>>>>> <eTypeArguments eClassifier="#//Overlay">
>>>>> <eTypeArguments/>
>>>>> </eTypeArguments>
>>>>> </eGenericType>
>>>>> </eStructuralFeatures>
>>>>> <eGenericSuperTypes
>>>>> eClassifier="#//AbstractEmfBasedAtomicFactory">
>>>>> <eTypeArguments
>>>>> eTypeParameter="#//EmfBasedOverlaidAtomicFactory/T"/>
>>>>> </eGenericSuperTypes>
>>>>> </eClassifiers>
>>>>>
>>>>> <eClassifiers xsi:type="ecore:EClass" name="AtomicFactory"
>>>>> abstract="true" interface="true">
>>>>> <eTypeParameters name="T"/>
>>>>> <eOperations name="create">
>>>>> <eGenericType eTypeParameter="#//AtomicFactory/T"/>
>>>>> </eOperations>
>>>>> <eStructuralFeatures xsi:type="ecore:EAttribute" name="type"
>>>>> changeable="false"
>>>>> volatile="true" transient="true" derived="true">
>>>>> <eGenericType eClassifier="ecore:EDataType
>>>>> http://www.eclipse.org/emf/2002/Ecore#//EJavaClass">
>>>>> <eTypeArguments eTypeParameter="#//AtomicFactory/T"/>
>>>>> </eGenericType>
>>>>> </eStructuralFeatures>
>>>>> </eClassifiers>
>>>>>
>>>>> <eClassifiers xsi:type="ecore:EClass" name="Overlay"
>>>>> abstract="true"
>>>>> interface="true">
>>>>> <eTypeParameters name="L"/>
>>>>> <eOperations name="initialize"/>
>>>>> <eStructuralFeatures xsi:type="ecore:EAttribute" name="overlaid">
>>>>> <eGenericType eTypeParameter="#//Overlay/L"/>
>>>>> </eStructuralFeatures>
>>>>> </eClassifiers>
>>>>>
>>>>>>>
>>>>>>>
>>>>>>> What's the best way to cope with this situation?
>>>>>>>
>>>>>>>
>>>>>>> I understand that having runtime type information about the
>>>>>>> component
>>>>>>> type of the list is certainly an advantage. Java doesn't provide
>>>>>>> that
>>>>>>> due to type erasure and the relation between <T> and Class<T> at
>>>>>>> least
>>>>>>> ensures that the programmer provides the right runtime type. In
>>>>>>> this
>>>>>>> case the code generator has to do it right.
>>>>>>>
>>>>>>> Seems to be one of those Java Generics traps. Maybe it would be
>>>>>>> better
>>>>>>> to just let the code generator provide the type without binding the
>>>>>>> type argument to the Class<T> object, i.e. change the signature of
>>>>>>> the
>>>>>>> constructor from
>>>>>> Maybe, but I'd have to consider whether that breaks API for
>>>>>> existing use
>>>>>> cases...
>>>>> Couldn't you add that as an option to the genmodel?
>>>> Changes the classes in the runtime is a different issue from changing
>>>> what's generated via the templates.
>>> Ehm, sorry of course changing the constructor would affect the
>>> runtime. The only thing you could do with the templates is to add some
>>> code to work around the problem, i.e. a type cast to
>>> BasicInternalEList without generic type arguments. Example:
>>>
>>> @SuppressWarnings({ "unchecked", "rawtypes" })
>>> public List<AtomicFactory<Overlay<?>>> getOverlayFactories() {
>>> if (overlayFactories == null) {
>>> overlayFactories = (BasicInternalEList) new
>>> BasicInternalEList<AtomicFactory>(
>>> AtomicFactory.class);
>>> }
>>> return overlayFactories;
>>> }
>>>
>>>>>>>
>>>>>>> public BasicInternalEList(Class<? extends E> dataClass)
>>>>>>>
>>>>>>> to
>>>>>>>
>>>>>>> public BasicInternalEList(Class<?> dataClass)
>>>>>>>
>>>>>>> BTW: Eclipse suggest a solution to the above compiler error which
>>>>>>> indeeds compiles but only with the Eclipse compiler:
>>>>>>>
>>>>>>> overlayFactories = new
>>>>>>> BasicInternalEList<AtomicFactory<Overlay<?>>>(
>>>>>>> (Class<? extends AtomicFactory<Overlay<?>>>)
>>>>>>> AtomicFactory.class);
>>>>>>>
>>>>>>> The javac compiler does not accept that solution, it says (package
>>>>>>> names removed)
>>>>>>>
>>>>>>> inconvertible types
>>>>>>> found :
>>>>>>> Class<AtomicFactory>
>>>>>>> required:
>>>>>>> Class<? extends AtomicFactory<Overlay<?>>>
>>>>>> Please open a bugzilla with a test case an I'll look more closely.
>>>>> Well, I never did this before, so it's gonna take some time.
>>>> That's better than me spending the time trying to create a test case
>>>> from scratch or from snippets. :-P
>>> What about this:
>>> I'll create the test case (I assume a minimal ecore model) and you
>>> make it into a bugzilla call?
>> Yes, I'll have a look. It should work properly, but I don't think it's
>> a good pattern to use...
> It's a nasty workaround and fixing it in the runtime is definitely the
> cleaner way. If you don not want to change the BasicInternalEList
> constructors in the runtime what about adding an improved version of
> BasicInternalEList to the runtime and changing the templates to use
> the new implementation if switched on in the genmodel.
>
> Regards,
> Dirk
>>>
>>> Regards,
>>> Dirk
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Thanks and regards,
>>>>>>> Dirk
>>>>>>
>>>>> Regards,
>>>>> Dirk
>>>>
>>>
>>
>
Previous Topic:[CDO] Do a rollback only for one resource
Next Topic:[CDO] Questions about Lazy loading ?
Goto Forum:
  


Current Time: Wed Nov 26 09:17:32 GMT 2014

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

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