[Edapt] ClassCastException when migrating models with InstanceClassName-attributes [message #1814797] |
Wed, 18 September 2019 09:46  |
Eclipse User |
|
|
|
We use Edapt 1.3.0 for our EMF-model-migration. Some of the EClasses are using the instanceClassName-attribute to implement non-EMF java interfaces.
On Migration, we run into a ClassCastException in EStructuralFeatureImpl::dynamicSet. As Edapt is creating DynamicEObjects, EClassifierImpl::isInstance does return false as can be seen in the following snippet taken from the source of EClassifierImpl:
public boolean isInstance(Object object)
{
if (object != null)
{
Class<?> instanceClass = getInstanceClass();
if (instanceClass != null)
{
if (instanceClass.isPrimitive())
{
...
}
else
{
return instanceClass.isInstance(object); // as object is a DynamicEObject, this will (wrongly) return false
}
}
else if (object instanceof EObject)
{
return dynamicIsInstance((EObject)object);
}
}
return false;
}
I can circumnavigate this issue by registering a custom implementation of EFactory with the extension "org.eclipse.emf.edapt.factories" that is setting the instance class simply to null, but altering the model like this seems a bit "smelly". As I understand this class is only creating classes by the dynamic ecore-model created by edapt where instance classes can be ignored down the line.
public class EdaptMigrationFactory extends EFactoryImpl {
@Override
public EObject create(EClass eClass) {
if (eClass.getInstanceClass() != java.util.Map.Entry.class) // EMF's map entries are correctly handled
eClass.setInstanceClass(null);
return super.create(eClass);
}
Is there a (quick) fix that you would rather suggest? Of course, the best would be if Edapt does not set the InstanceClasses at all.
|
|
|
|
Re: [Edapt] ClassCastException when migrating models with InstanceClassName-attributes [message #1815670 is a reply to message #1814797] |
Tue, 08 October 2019 04:43  |
Eclipse User |
|
|
|
Hi,
I think there is no way to avoid a custom EFactory here when working with Dynamic EMF. However I think you could structure your Ecore a bit differently to avoid this issue.
If I understood your use case correctly you want to implement a custom Java interface for some EClasses.
I would suggest to create an empty EClass for this interface, set interface to true, but don't add an instance type name in the ecore.
Add this new EClass as a supertype for the appropriate EClasses and generate the code.
Go to the generated Java interface you just created and add an extends for your actual Java interface in the code. Change @generated to @generated NOT.
As this interface EClass is empty and should stay empty in the model, there is no harm switching to @generated NOT, as this should not change in the future. Regenerating will not remove this extends.
This should help to avoid those issues with dynamic EMF.
I hope this helps.
Cheers, Johannes
|
|
|
Powered by
FUDForum. Page generated in 0.04174 seconds