Monday, September 29, 2008

OSGi: JAXB with OSGi

For the past few months I have kept my head down, kept a low profile, and have been studying and learning things that I have had little to no experience with. One such thing is working with building applications with the OSGi framework. I have come across a number of good articles that have explained how to build OSGi based applications in all the major implementations. The better of all the articles are listed here:

But I ran into some issues with the project I was working on. All of these issues had to do with Classloaders in the OSGI framework not being compatible with whatever packages I was working with. One such case was with JAXB.

Fortunatly, I came across the DynamicJava website. These guys seem dedicated to creating OSGi Launchers and JSR API's that are compatible with OSGi. Neat trick, and they work too. However, to get these to work within Eclipse is another story all together.

First, download the following packages from their site:
  • STAX
  • JPA
  • JAXB
All of these are necessary for JAXB to work. Create three projects in Eclipse, each with their respective names off STAX, JPA, and JAXB. In my case, I created these three projects:

  • org.dynamicjava.jsr.jaxb_api
  • org.dynamicjava.jsr.jpa_api
  • org.dynamicjava.jsr.stax_api
Extract the three archives downloaded into the respective packages. In my case, I moved all the source files into the /src folders under their plugin folders.

For the STAX package, the only modification that needed to be made was in the build.properties file. It should read like so:

source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

Be sure to include the dot on the line for bin.includes. Eclipse did a really strange thing where it kept losing it for me.

I did end up needing to make a few changes for the JPA_API plugin. The MANIFEST.MF read as follows when I was done:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.dynamicjava.jsr.jpa_api
Bundle-Version: 1.0.0
Bundle-Activator: javax.persistence.internal.Activator
Bundle-Name: DynamicJava.org: JSR: JPA-API
Export-Package: javax.persistence;version="1.0.0",
javax.persistence.internal,
javax.persistence.internal.classloading_utils,
javax.persistence.internal.support,
javax.persistence.spi;version="1.0.0"
Import-Package: org.osgi.framework
Require-Bundle: org.eclipse.osgi


The Build.properties was exactly the same as the STAX_API.

If both projects are building correctly in Eclipse, then the final part will be to get JAXB working. This one really proved to be a big PITA. First, download the geronimo-activation_1.1_spec-1.0.2.jar. This jar is available inside of the test program that the Dynamic Java guys provide. The JPA plugin should contain this, however I had issues putting this into the JPA plugin, so I ended up putting it into the JAXB plugin (which I may change at some point). Download the jar and put it into the /lib folder in the JAXB plugin. You will also need the jaxb-impl.jar file, available in the same archive.

From there, the Manifest.MF for the JAXB project should read like so:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.dynamicjava.jsr.jaxb_api
Bundle-Version: 1.0.0
Bundle-Activator: javax.xml.bind.internal.Activator
Bundle-Name: DynamicJava.org: JSR: JAXB-API
Export-Package: com.sun.xml.bind,
com.sun.xml.bind.v2,
javax.activation,
javax.xml.bind;version="2.1.0",
javax.xml.bind.annotation;version="2.1.0",
javax.xml.bind.annotation.adapters;version="2.1.0",
javax.xml.bind.attachment;version="2.1.0",
javax.xml.bind.helpers;version="2.1.0",
javax.xml.bind.util;version="2.1.0"
Import-Package: javax.xml.namespace,
javax.xml.stream;version="1.0.0",
javax.xml.transform
Bundle-License: http://www.opensource.org/licenses/cddl1.php
Require-Bundle: org.dynamicjava.jsr.stax_api,
org.dynamicjava.jsr.jpa_api,
org.eclipse.osgi
Bundle-ClassPath: lib/jaxb-impl.jar,
.,
lib/geronimo-activation_1.1_spec-1.0.2.jar

The Build.properties files needs to be modified to read like so:

source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
lib/jaxb-impl.jar,\
lib/geronimo-activation_1.1_spec-1.0.2.jar

Now, you can use JAXB from within OSGi.