Eclipse Blog

How to properly override the generated EMF code?

How to properly override the generated EMF code?

EMF allows generating code from the model. By parameterizing the .genmodel file, we can generate 3 sources of code: model, edit and editor, which contain the java sources that let exploit the defined model.
In order to override the generated code, the traditional method consists in directly modifying the generated code by adding a ‘NOT’ behind the @generated tags. Additionally, the ‘mint’ plugin (in emftool) allows distinguishing the overridden methods (in red) from the added methods (in black) and the generated methods (in blue):

The overridden code with @generated

 

This method is acceptable if little code is modified, however, in the event of projects in which a lot of generated job code has to be added, then it is recommended to:

  • clearly separate the generated code from manual code
  • automatically generate the code when starting the build process
  • take out the generated code from the configuration version system (cvs, svn, git, …) and generate it again when the delivery is made

EMF and Eclipse offer simple solutions to answer this need.
 

1. Separating the src-gen and the src

In order to work properly, it is important to take ‘sealing’ measures, by clearly separating the generated code from the overriddden code. To do this, parameterize the model using the following instructions:

Parameterizing of the genmodel

This operation can be repeated for the edit layer and editor layer.
Then, create a src directory (folder source), dedicated to override the project:

src directory for the override

 

This new source directory will contain a new EMF factory for creating the instances of the overridden classes. This factory comes from the generated factory and permits object creation with the new interfaces:

New factory that creates the new instances

 

We will complete the methods of this factory as we override the classes of the generated model.

So, the implementation of the factory is simple:

Implementation of the overridden factory

 

Then, you just need to link the new factory to EMF by using the extension point factory_override:

extension point override_factory

This new factory will automatically be used by EMF during the object creation by a call to RentalFactory.eInstance.

 

Then, the modeled classes only need to be overridden with EMF. In this way, helper methods (add, remove) can be added in the interfaces … :

Adding access methods in the interface

 

… and the modelized operations can be overridden in the implementation:

Implementation of the job methods in the interface

 

 

2. Generating the code in Eclipse during the build

If we totally separate the generated code from the overridden code, it can be useful to automate the code generation from the model.

EMF offers us an ant task (emf.Ecore2Java) that allows generating code from a genmodel. Writing the ant file is straightforward:

Ant file to generate EMF code

 

To execute it, it is important to use the JRE from the workspace (parameter of the build launch, in the JRE tab).

This ant file can then be integrated to the project builder by putting it in the first position in order to ensure that that the generated code is present for the compilation:

 

 

 

3. Generating the code during the build, outside Eclipse

In the build headless process, without having and Eclipse IDE launched, we can generate code both ways,

  • using the application org.eclipse.ant.core.antRunner which calls the generation ant which can contain the following tasks
  • using the application org.eclipse.emf.codegen.ecore.Generator which only does generation

In both cases, the launch environment has to be set up:

  • cd {Installation directory of Eclipse Modeling}
  • export LAUNCHER=plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar

Generating with the antRunner :

Launch of the build with the antRunner :
java -jar $LAUNCHER -application org.eclipse.ant.core.antRunner -nosplash -buildfile {pathToAntFile}/ecore2java.xml

This method is useful if the ant file does a bit more than that of the code generation.

Generating with the ecore.Generator

This method is useful if there is only code to generate from the model:

The parameters of the application are: java -jar $LAUNCHER -application org.eclipse.emf.codegen.ecore.Generator
Usage arguments: [-projects ]
[-dynamicTemplates] [-forceOverwrite | -diff]
[-generateSchema] [-nonNLSMarkers]
[-codeFormatting { default | } ]
[-model] [-edit] [-editor] [-tests]
[-autoBuild true | false ]
genmodel-file [ target-root-directory ]

Example:

  • export PROJECT_HOME={path to your project}
  • java -jar $LAUNCHER -application org.eclipse.emf.codegen.ecore.Generator -projects $PROJECT_HOME -model -nosplash $PROJECT_HOME/model/rental.genmodel $PROJECT_HOME

In order to go deeper in these notions, I advise you to read this general article on the matter, presented atinfoq and written by Sven Efftinge (XText project manager)

 

Feel free to comment this article if you have remarks !

User Comments


  1. OPCoach
    23 October 2014

    Hi Francois,
    It is probably possible to extract the ‘JET’ component from the emf plugins and to have a very small java launching this generation. But launching an OSGi application is as difficult as a Java application. So why would you like to have a ‘main’ java for that ?
    Then if you have some java you can easily launch it from maven.
    You can write me an email or call me by phone if you want to explore these ideas.. (see the contact page of the site)
    Olivier


  2. Francois
    23 October 2014

    Dear Olivier,
    very could post.
    I have still one question: is it possible to generate the code with emf from ecore/genmodel without any eclipse IDE?
    In both case, it seems that you need to be in a eclipse environment even if you call the method by command line.
    Is there a way for instance to integrate it in a maven build? totally independant from Eclipse environment?
    Thanks
    Francois, from France


  3. Francois
    6 October 2014

    Dear Olivier,
    thanks for this synthesis.
    could you also explain how to call the code generator directly from a java class with a main.
    I am trying to setup a maven plugin project dedicated to generate this.
    Thanks for your help

Leave a Reply