Pages

Showing posts with label Eclipse. Show all posts
Showing posts with label Eclipse. Show all posts

Wednesday, February 15, 2012

Eclipse RCP P2 self-update


I have been working last time in order to add update mechanism to Eclipse RCP application we have developed in my team. I must confess I struggled for some time with the P2 mechanism and finally I succeeded to obtain the expected result: an RCP based application with an automatic self-update mechanism, using headless build and testable with Jenkins.


Adding self-update to an application is not a ordinary or easy task. There are few examples here, here, or here
I tried different solution and there were always some scenarios that didn’t work properly (headless build did not work as expected,  problems with dependencies in eclipse.equinox.p2.user.ui, plug-in org.eclipse.equinox.ds not started and the most frustrating the updates were not detected). Therefore, my colleagues agreed all that P2 mechanism is "unnecessary complicated".  


Here are steps that I followed in order to have the provisioning mechanism working.
  • Create a feature-based product (a simple RCP Application to which we will add features)
  •  Export the product
  •  Export features to be included in the application
  • Install features to the result application. You may add them manually using the Install New Software menu or use a command line or script. For instance you may use:

%eclipse_home%/eclipsec.exe -application org.eclipse.equinox.p2.director -repository <list_of_comma_separated_repositories>  -installIU <your_feature_group> -destination <location_of_targeted_product>  -profile <profile>
  • Modify your bundles and features version number
  • Export again the features and deploy them optionally on a web server
  • Start your application and check for updates (update sites may be added at he runtime, in the code or using p2.inf file to have pre-defined locations): it should detect the updated features. Additionally, I added headless update at startup as described here

I hope this will help you to have your P2 working. I will publish soon the source code and scripts for this application.

Monday, November 14, 2011

Using EMF in standalone Java application


During the last days I was working with Eclipse Modeling Framework (EMF) within the context of an R&D project. As our architecture became distributed, I had to use EMF outside an Eclipse-based application. Therefore, this article deals with us of EMF in a standalone Java application (standalone meaning here not running in en Eclipse framework like server-side components, Swing applications, etc). I will not present here how to use EMF to create models and generate the respective Java code (you may find a good tutorial on that at http://www.vogella.de/articles/EclipseEMF/article.html), but I will focus on using the generated code in a standalone Java application.

Let us remind that EMF project is a modeling framework and code generation facility for building tools and other applications based on a structured data model. Models can be specified using annotated Java, XML documents, or modeling tools and then can be used to produce a set of Java classes for the model, along with a set of adapter, factories and utility classes. You may find information and  documentation about the EMF project at http://www.eclipse.org/modeling/emf/docs/ .

Naturally, EMF (and its subprojects: EMF Core, CDO, Compare, Teneo, Model Query, etc) fits well in an Eclipse environment (Eclipse IDE or RCP). Nevertheless, EMF’s runtime features (use of generated code, notification, change recording, validation, persistence, etc) can be used in a standalone Java application. In order to benefits from EMF in such application, you must add all the needed jars to your classpath. In the book “EMF Eclipse Modelling Framework” you may find a table that clearly identifies the required jars based on the desired feature:

  • Core runtime, reflective API, validation: org.eclipse.emf.common_<version>.jar and org.eclipse.emf.ecore_<version>.jar
  • XML/XMI persistence: org.eclipse.emf.ecore.xmi_<version>.jar and the previous core runtime jars
  • EMF.Edit: org.eclipse.emf.edit_<version>.jar and the core runtime jars
  • Change model: org.eclipse.emf.change_<version>.jar and the core runtime jars
  • Ecore to XML persistence mapping: org.eclipse.emf.mapping.exore2xml_<version>.jar and the core runtime and XML/XMI jars
  • XML schema Infoset Model: org.eclipse.xsd_<version>.jar and the core runtime jars.


When using EMF under Eclipse, the plug-in extension mechanism is used to perform registration at runtime. In a standalone environment, default resource factories are not registered. Therefore, for each file extension or scheme the application wants to load or save, one needs to register the corresponding resource factory. For example, to load and save XML documents, it is necessary to add a similar line in your the application:
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("xml", new XMLResourceFactoryImpl());

In addition, one also needs to register one’s package, which happens as a side effect of accessing XyzPackage.eINSTANCE attribute. For example, to register the example model, it is necessary to add the following lines to the program:
MyEMFExamplePackage.eINSTANCE.eClass();
   ChangePackage.eINSTANCE.eClass(); // only if using EMF change feature

In my application I choose to code a class ResourceManager (which additionally is a Singleton) and put all these registrations in the initialization part of this object.
public class ResourceManager {

 /**
  * Create the resource manager.
  */
 private ResourceManager() {
  
  resourceSet = createResourceSet();

  // register factories
  Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("xml", new XMLResourceFactoryImpl());

  // register packages
  MyEMFExamplePackage.eINSTANCE.eClass();
  ChangePackage.eINSTANCE.eClass(); // only if using EMF change feature
 }

 /**
  * Create the resource set.
  */
 private ResourceSet createResourceSet() {
  ResourceSet rs = new ResourceSetImpl();
  // Register the default resource factory -- only needed for stand-alone
  rs.getResourceFactoryRegistry()
    .getExtensionToFactoryMap()
    .put(Resource.Factory.Registry.DEFAULT_EXTENSION,
      new XMIResourceFactoryImpl());
  rs.setURIConverter(new MapItURIConverter());

  return rs;
 }
 
 // Other methods ...
}

Now that we have registered all needed factories and packages, we can use the code generated by EMF in order to manipulate, save and load objects. In this example I instantiate a “dummy” model and, save it in an xml file. Subsequently,  I load the model and record the modification in order to apply it later.

In this entry, we have seen an example of using EMF outside Eclipse, i.e., in a standalone Java application which could be a server component, a Swing GUI etc. It is to note that in order to use EMF feature in such environment, it is necessary to perform two important steps:

  • Add required jars in the classpath
  • Register Factories and packages prior to model utilization.


/* */