背景:在 karaf,我有两个功能,每个功能都使用不同版本的 Jersey(1.17 和 2.0)。
它们是相互分离的,并且没有同时导入它们的包。
Jersey 1.17 和 2.0 之间的包名称已更改(com.sun.jersey 与 org.glassfish.jersey)。
无论如何,使用 jersey 1.17 的捆绑包可以正常工作。
为了使 2.0 工作(大概),我在某处读到我可以在我的 jar/bundle 的 META-INF 目录中名为“services”的目录中的文件中为消息阅读器指定提供程序的 FQN。(根据http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider)
看起来像这样:
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
它似乎正在工作,因为我的 org.glassfish.jersey.core.jersey-common 2.0 捆绑包尝试加载第一个类。但它会抛出一个 ClassNotFoundException 。
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]
请注意,这发生在 bundle 207 jersey-common 2.0
如果我跑
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
课程就在那里,在同一个捆绑包中!它在自己的包中找不到类。
这对我来说毫无意义,除非 glassfish 以某种方式使用其他类加载器。任何人都可以对此有所了解吗?
谢谢。
更新 我发现了这个错误:
https://java.net/jira/browse/GLASSFISH-16970
这让我找到了关于这个问题的 wiki:
https://wikis.oracle.com/display/GlassFish/JdkSpiOsgi
我不知道如何在不破坏 jersey-core-common jar 的情况下实现他们的解决方法。