Java EE specs in OSGi
For ServiceMix 4, I've been working on making sure the Java EE specifications can be used in OSGi. The first step was to release OSGi versions of the various specifications by just adding the needed manifest entries to make them usable in OSGi. This was done inside the Geronimo project (on which I am a committer). This means that since a few months, most of the Java EE specification jars are available as OSGi bundles (you can grab those from maven 2 public repositories.
However, this is not always sufficient. Some of these specifications (mostly JAXB, SAAJ, JAX-WS and Stax) do not work well in OSGi. The mean reason is that the implementation is discovered using different mechanisms by the API. The most commonly used one is to find a file on the classpath in the
The solution came to me after a chat with Dan Kulp: an OSGi specific discovery mechanism can be easily plugged into these spec jars. It consists in two small classes shared amongst these spec jars: an OSGi bundle activator and another class not tied to the OSGi api that maintain a list of available implementations. The final step if to rewrite the factory of those jars to look inside this map before performing the usual lookup.
This means that in a non OSGi environment, the jar behaves as usual, but when deployed into an OSGi runtime such as ServiceMix Kernel, the spec bundle will be able to locate dynamically the implementation to use. Therefore, the client bundle using the spec jar is now free of any requirements.
However, this is not always sufficient. Some of these specifications (mostly JAXB, SAAJ, JAX-WS and Stax) do not work well in OSGi. The mean reason is that the implementation is discovered using different mechanisms by the API. The most commonly used one is to find a file on the classpath in the
META-INF/services
directory and find the main entry point class of the implementation. Unfortunately, to make this work in OSGi, the client bundle (the one using one of these APIs) has to have the required file in its classpath, which means the inability to use one provided by the runtime in which the bundle is deployed and that it can not be switched without changing and re-compiling the bundle. Another way would be to add a Require-Bundle OSGi manifest so that the classpath of the implementation becomes part of the client bundle, but this also ties the client bundle to the implementation used. The solution came to me after a chat with Dan Kulp: an OSGi specific discovery mechanism can be easily plugged into these spec jars. It consists in two small classes shared amongst these spec jars: an OSGi bundle activator and another class not tied to the OSGi api that maintain a list of available implementations. The final step if to rewrite the factory of those jars to look inside this map before performing the usual lookup.
This means that in a non OSGi environment, the jar behaves as usual, but when deployed into an OSGi runtime such as ServiceMix Kernel, the spec bundle will be able to locate dynamically the implementation to use. Therefore, the client bundle using the spec jar is now free of any requirements.
Comments
Thanks again.
You can find pre-built binaries on the following repository.
Btw, I did not say it was Dan's technique, I just said I found this technique while chatting with Dan ;-)
If you can change the spec JAR, then I think there is an even nicer possibility. Instead of prescanning the bundles, you can just also look in the OSGi service registry when the factory is used. An independent bundle will then do the scanning of the implementation jars and register implementations under their factory interface. This scanning bundle is shared between ALL different META-INF/services users. If all spec starts to scan all bundles, this might become expensive.
Also, this would allow implementation JARs to just register their implementations directly. Which opens all kind of nice possibilities like remote implementations, etc.
For interoperation, OSGi services beat class loader hacks anytime imho :-)
But anyway, I think this is great that these compatibility issues are addressed!
Kind regards,
Peter Kriens
I agree with you. This was discussed on the Geronimo list a while back, http://www.nabble.com/Geronimo-specs-jars-in-OSGi-td16726438s134.html.
There, Guillaume pointed out the added benefit of running multiple versions, e.g. jaxb 2.0 / 2.1, concurrently. The problem is with legacy code that would not have the requisite service registration code.
Good blog BTW.
Regards,
Alan
But I also think that in many cases it is perfectly in order that you simply package jars like an XML Parser with each bundle that needs it. I do not think that OSGI services have to be used for fine granular things. They are much more useful for modularizing your business aplication than for basic libs.
Of course, the best would be to use ServiceLoader, but I do know that that is not an option as the requirement is just too high.
http://feboook.blogspot.com