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.
