Friday, 17 September 2010

Apache Aries JPA samples

There are two things that I almost always get caught by when developing samples for Apache Aries which use the JPA capabilities. The first is to do with datasources, the second is to do with enhancing persistence entities.

I get caught out because these two things would normally be provided by a JEE compliant container - something like the WebSphere App server - so,  as an application developer I would not normally have to think too much about them. However, all of the Aries samples need to be able to run in an OSGi platform built up using a set of readily available open source bundles so we need to find ways to do things that an app server would normally do for us.

Datasources

If you look at the source for the Apache Aries blog sample  you will find that the JPA persistence bundle depends on being able to use two other bundles. The relationships are like this:





On the left, shown in yellow, is the blog-jpa-persistence bundle. This is part of the blog sample application. Inside that bundle there are two important xml files, one with blueprint configuration, the other with persistence information. Configuration in these two files points to things supplied by the other two bundles.

The middle (green) and right hand side bundles (mauve) are both providing function that would normally be part of  an app server. The green one (transaction-wrappers) is available as part of Aries, it's a really simple implementation of function to enlist a data source. This is provided in Aries as a convenience for people writing samples. The 'datasource' bundle is something that needs to be  provided by the application developer but is not part of the application, there is no Java code to write - just a little blueprint which points to your database. For an example - look at the blueprint configuration in the blog sample data source. If you were using an app server you would normally configure data sources through an admin screen - providing the data source bundle is doing just the same thing.

When you assemble the OSGi platform that you will use to run your application you will need to make sure that both the transaction-wrappers bundle and your datasource bundle are running in the platform before you drop your OSGi application onto the load directory to be run. If you are in any doubt about how to assemble the kind of OSGi platforn you will need have a look at the blog-assembly project in Aries.

Enhancing persistence entities

The other part of JPA that I always get bitten by is the need to enhance  persistence entities. Enhancing means running a utility  that takes the byte code for persistence entities, processes it and spits out another, vastly more efficient and much larger, set of byte codes. This is again something that a fully compliant JEE container be expected to do for you - so you probably wouldn't be aware of it. There are various ways to enhance persistence  entities, in the Aries samples we use Maven, look at the pom.xml in samples/blog/blog-persistence-jpa/ to see how. Sadly, not everyone likes Maven as much as I do, so here is how to do it using Eclipse.

In this example I'm using the Eclipse JEE (Helios) development platform with the "IBM Rational Development Tools for OSGi Applications 0.6" installed. This is convenient because I can work on the code, build it and then export it as an OSGi application (.eba file). The .eba file can be dropped into the 'load' directory of my Aries platform to be run.

My Eclipse screen looks like this:




I'm using a sample Stocks application; the biz module has some persistence entities and the persistence xml is in it's default location in the META-INF directory.  To enhance the entities we need to run en external tool. Click on the external tools drop-down (the thing with a little red suitcase in the top bar) and then external tools configuration. From the next screen, select 'Program' and then 'new' (a white rectangle with a yellow cross in the corner). You should see something like this:


For 'Name', type in JPA_enhancer. Then, in the 'Location' field add the location of your Java executable. For me this is: /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/bin/java.

Now the fun begins. Under 'Arguments' you will need to add the command to run the JPA enhancer, for me this looks something like:

-cp MYJARS/commons-collections-3.2.1.jar:MYJARS/geronimo-jta_1.1_spec-1.1.1.jar:MYJARS/geronimo-jpa_2.0_spec-1.0.jar:MYJARS/openjpa-2.0.0.jar:MYJARS/commons-lang-2.5.jar:MYJARS/org.apache.servicemix.bundles.serp-1.13.1_2.jar:MYWKSP/org.apache.stocks.biz/bin:MYWKSP/org.apache.stocks.api/bin:MYWKSP/org.apache.stocks.biz/src org.apache.openjpa.enhance.PCEnhancer

where MYJARS is the path to a directory where I have copies of all the jars I need. MYWKSP is the path to the sample code.

It's easiest to think about this in three parts. First,  all the jars that the enhancer need on the classpath, these are:

  • commons-collections-3.2.1.jar
  • geronimo-jta_1.1_spec-1.1.1.jar
  • geronimo-jpa_2.0_spec-1.1.jar
  • openjpa-2.0.0.jar
  • commons-lang-2.5.jar
  • org.apache.servicemix.bundles.serp-1.13.1_2.jar

Then you'll need the class files and the source for your persistence entities and the class files for any API they depend on, thus:

  • org.apache.stocks.biz/bin
  • org.apache.stocks.api/bin
  • org.apache.stocks.biz/src

Finally the name of the program that you are going to run :

  • org.apache.openjpa.enhance.PCEnhancer

Adding that command (with your own paths of course) and saving the configuration should get you to the point where you can run your JPA_enhancer. The easiest way to check that it has worked (apart from there being no obvious errors) is to look at the size of the class files  - they should be much larger than the unenhanced versions.

Before exporting the OSGi application you will  need to modify the MANIFEST.MF of your persistence bundle to make sure that the import-package contains:

org.apache.openjpa.enhance;version="[2.0,3)",org.apache.openjpa.util;version="[2.0,3)"

Don't worry if Eclipse complains about this. Finally - just export the project as an OSGi Application (EBA) and run it by adding it to the load directory of your OSGi platform.

No comments: