Background: in karaf, I have two features that each use a different version of Jersey (1.17 and 2.0).
They are separated from each other and there are no bundles that import both of them.
The package names between 1.17 and 2.0 of Jersey have changed (com.sun.jersey vs. org.glassfish.jersey).
Anyway, the bundles that use jersey 1.17 work fine.
To make 2.0 work (presumably), I read somewhere that I can specify FQN of providers for message readers in a file in a directory called "services" in my META-INF dir in my jar/bundle. (as per http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider )
That looks like this:
META-INF/services/javax.ws.rs.ext.MessageBodyReader:
org.glassfish.jersey.message.internal.XmlRootObjectJaxbProvider.App
org.glassfish.jersey.message.internal.SourceProvider.StreamSourceReader
org.glassfish.jersey.message.internal.SourceProvider.SaxSourceReader
org.glassfish.jersey.message.internal.SourceProvider.DomSourceReader
org.glassfish.jersey.message.internal.XmlRootObjectJaxbProvider.Text
org.glassfish.jersey.message.internal.XmlRootObjectJaxbProvider.General
It seems to be working, because my org.glassfish.jersey.core.jersey-common 2.0 bundle attempts to load the first class. But it throws a ClassNotFoundException on it.
2013-07-29 14:36:45,334 | WARN | Executor: 2 | OsgiRegistry | egistry$BundleSpiProvidersLoader 222 | 207 - org.glassfish.jersey.core.jersey-common - 2.0.0 | [] | Exception caught while loading SPI providers.
java.lang.ClassNotFoundException: org.glassfish.jersey.message.internal.XmlRootObjectJaxbProvider.App
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:501)[osgi-3.8.0.v20120529-1548.jar:]
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)[osgi-3.8.0.v20120529-1548.jar:]
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)[osgi-3.8.0.v20120529-1548.jar:]
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)[osgi-3.8.0.v20120529-1548.jar:]
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)[:1.7.0_21]
at org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:340)[osgi-3.8.0.v20120529-1548.jar:]
at org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:229)[osgi-3.8.0.v20120529-1548.jar:]
at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1212)[osgi-3.8.0.v20120529-1548.jar:]
at org.glassfish.jersey.internal.OsgiRegistry$BundleSpiProvidersLoader.call(OsgiRegistry.java:217)[207:org.glassfish.jersey.core.jersey-common:2.0.0]
at org.glassfish.jersey.internal.OsgiRegistry$BundleSpiProvidersLoader.call(OsgiRegistry.java:189)[207:org.glassfish.jersey.core.jersey-common:2.0.0]
at org.glassfish.jersey.internal.OsgiRegistry.locateAllProviders(OsgiRegistry.java:468)[207:org.glassfish.jersey.core.jersey-common:2.0.0]
Note this is happening in bundle 207 jersey-common 2.0
if I run
karaf@root> osgi:find-class XmlRootObjectJaxbProvider
jersey-core-common (207)
org/glassfish/jersey/message/internal/XmlRootObjectJaxbProvider$App.class
org/glassfish/jersey/message/internal/XmlRootObjectJaxbProvider$General.class
org/glassfish/jersey/message/internal/XmlRootObjectJaxbProvider$Text.class
org/glassfish/jersey/message/internal/XmlRootObjectJaxbProvider.class
The class is right there, in the same bundle! It cannot find a class in its own bundle.
This makes no sense to me, unless glassfish is using some other class loader somehow. Can anyone shed any light on this?
Thanks.
update I found this bug:
https://java.net/jira/browse/GLASSFISH-16970
which lead me to this wiki on the matter:
https://wikis.oracle.com/display/GlassFish/JdkSpiOsgi
I don't see how I could implement their work-around without hacking up the jersey-core-common jar.