Home » Modeling » EMF » Coupled evolution problem
Coupled evolution problem [message #1727482] |
Wed, 23 March 2016 10:35 |
Vlad Acretoaie Messages: 95 Registered: April 2014 |
Member |
|
|
Hi,
I have an Eclipse RCP application that uses EMF and relies on Java classes generated from several Ecore models. These Ecore models have recently been modified, implying that instances of the old Ecore models can no longer be opened in the application. The old instance models have to be migrated so that they conform to the new version of the Ecore models. In other words, this is a coupled evolution problem.
My current approach is to use the EMF Reflection API and Persistence API to evolve the old models. I need the Reflection API because at runtime I only have access to the new version of the generated Java classes, so I just use reflection to navigate through the old models.
However, I have hit a setback when trying to load a model conforming to the old metamodel into a Resource. Namely, I have something like the following code snippet:
String pathToOldModel = ...
URI oldModelURI = URI.createFileURI(pathToOldModel);
Resource oldModelResource = resourceSet.createResource(oldModelURI);
oldModelResource.load(null);
At this point, the call to load(null) throws the following exception:
org.eclipse.emf.ecore.resource.Resource$IOWrappedException: Feature 'oldFeature' not found.
I presume this is because the Resource is attempting to use the updated Ecore model to load the old instance model, and feature 'oldFeature' does not exist in the updated Ecore model.
So, finally, my questions:
- Do I need to provide the old Ecore models to the Resource (or ResourceFactory)?
- If so, how can I do that?
Thanks in advance!
Cheers,
Vlad
|
|
|
Re: Coupled evolution problem [message #1727761 is a reply to message #1727482] |
Sun, 27 March 2016 00:25 |
Ed Merks Messages: 33140 Registered: July 2009 |
Senior Member |
|
|
Vlad,
Comments below.
On 23.03.2016 18:35, Vlad Acretoaie wrote:
> Hi,
>
> I have an Eclipse RCP application that uses EMF and relies on Java
> classes generated from several Ecore models. These Ecore models have
> recently been modified, implying that instances of the old Ecore models
> can no longer be opened in the application. The old instance models have
> to be migrated so that they conform to the new version of the Ecore
> models. In other words, this is a coupled evolution problem.
You might look into https://www.eclipse.org/edapt/
>
> My current approach is to use the EMF Reflection API and Persistence API
> to evolve the old models. I need the Reflection API because at runtime I
> only have access to the new version of the generated Java classes, so I
> just use reflection to navigate through the old models.
>
> However, I have hit a setback when trying to load a model conforming to
> the old metamodel into a Resource. Namely, I have something like the
> following code snippet:
>
>
> String pathToOldModel = ...
> URI oldModelURI = URI.createFileURI(pathToOldModel);
> Resource oldModelResource = resourceSet.createResource(oldModelURI);
> oldModelResource.load(null);
>
>
> At this point, the call to load(null) throws the following exception:
>
>
> org.eclipse.emf.ecore.resource.Resource$IOWrappedException: Feature
> 'oldFeature' not found.
>
>
> I presume this is because the Resource is attempting to use the updated
> Ecore model to load the old instance model, and feature 'oldFeature'
> does not exist in the updated Ecore model.
>
> So, finally, my questions:
>
>
> Do I need to provide the old Ecore models to the Resource (or
> ResourceFactory)?
> If so, how can I do that?
>
The resource set has a package registry. So you could load the old
*.ecore, extract the EPackage from that resource, register it in the
resource set's package registry. Google "Dynamic EMF" and you should
find some examples.
>
> Thanks in advance!
>
> Cheers,
> Vlad
>
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Re: Coupled evolution problem [message #1728421 is a reply to message #1727761] |
Mon, 04 April 2016 09:50 |
Vlad Acretoaie Messages: 95 Registered: April 2014 |
Member |
|
|
Dear Ed,
Thank you for your answer. I have indeed looked at Edapt, but found very little documentation on using it programmatically, so decided against using it for now.
I understand your proposed solution, but am not sure what you mean by "extract the EPackage from that resource". Is there a way to get an instance of EPackage from a Resource?
I did look up Dynamic EMF (also read the relevant section from EMF the book), and as far as I understand, it is necessary that the xsi:schemaLocation attribute is set in the Ecore file in order for the Package to be registered automatically with the ResourceSet. However, this attribute is not set in the Ecore files I am working with, so I will have to register the Package manually.
Cheers,
Vlad
|
|
|
Re: Coupled evolution problem [message #1728427 is a reply to message #1728421] |
Mon, 04 April 2016 10:07 |
Ed Merks Messages: 33140 Registered: July 2009 |
Senior Member |
|
|
Vlad,
Comments below.
On 04.04.2016 11:51, Vlad Acretoaie wrote:
> Dear Ed,
>
> Thank you for your answer. I have indeed looked at Edapt, but found
> very little documentation on using it programmatically, so decided
> against using it for now.
>
> I understand your proposed solution, but am not sure what you mean by
> "extract the EPackage from that resource". Is there a way to get an
> instance of EPackage from a Resource?
If you load a *.ecore resource the one root object in
Resource.getContents() will be an EPackage...
>
> I did look up Dynamic EMF (also read the relevant section from EMF the
> book), and as far as I understand, it is necessary that the
> xsi:schemaLocation attribute is set in the Ecore file in order for the
> Package to be registered automatically with the ResourceSet.
Yes, for it to automatically find the dynamic package.
> However, this attribute is not set in the Ecore files I am working with
You mean in your instance files.
> , so I will have to register the Package manually.
Yes, you would need to manually load the *.ecore resource with the old
representation of your model into a resource set, register that
resource's EPackage in the resource set's package registry, and then
when you load an instance resource into that resource set, it will use
the older dynamic presentation of your model to represent the instance.
You could then use reflection to extract the old information (reflection
using the old EPackage) and create an instance of the new model.
>
> Cheers,
> Vlad
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
| | |
Re: Coupled evolution problem [message #1728469 is a reply to message #1728465] |
Mon, 04 April 2016 15:05 |
Vlad Acretoaie Messages: 95 Registered: April 2014 |
Member |
|
|
Dear Ed,
Yes, you are right. I am loading several .ecore files, and some of them contain references to some of the others. These references were expressed using relative paths that became erroneous when I moved the .ecore files. After updating the relative paths, the NullPointerException no longer appears.
Right now I am using URI.createPlatformPluginURI(...) to get the URIs of the *.ecore resources to be loaded. I plan to distribute the old versions of my Ecore models together with my application (as part of a plugin, simply stored as any other files distributed with that plugin). Would this approach allow references to be resolved properly?
Cheers,
Vlad
[Updated on: Tue, 05 April 2016 07:59] Report message to a moderator
|
|
|
Re: Coupled evolution problem [message #1728510 is a reply to message #1728469] |
Tue, 05 April 2016 06:48 |
Ed Merks Messages: 33140 Registered: July 2009 |
Senior Member |
|
|
Vlad,
Comments below.
On 04.04.2016 17:05, Vlad Acretoaie wrote:
> Dear Ed,
>
> Yes, you are right. I am loading several .ecore files, and some of
> them contain references to some of the others. These references were
> expressed using relative paths that became erroneous when I moved the
> .ecore files. After updating the relative paths, the
> NullPointerException no longer appears.
Relative paths are not in and of themselves a problem, but keeping the
resources in relatively the same location is important.
>
> Right now I am using URI.createPlatformPluginURI(...) to get the URIs
> of the *.ecore resources to be loaded. I plan to distribute the old
> versions of my Ecore models together with my application (as part of a
> plugin, simply stored as any other files distributed with that
> plugin). Would this approach allow references to be resolved properly?
Yes, if everything is in the workspace originally then all resources are
loaded with platform:/resource/<project-name>/<path>. As such, all
serialized cross references are relative of the form
.../<more-..>/<project-name>/<path>. If the project-name and the
plugin-in are the same (which is general the practice), then loading a
resource with platform:/plugin/<plugin-in>/<path> will result in all
relative cross references normalizing to platform:/plugin.
>
> Cheers,
> Vlad
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
| | | |
Goto Forum:
Current Time: Tue Apr 23 08:16:04 GMT 2024
Powered by FUDForum. Page generated in 0.03845 seconds
|