【问题标题】:In Karaf OSGI, I am getting ClassNotFoundException for a class that is IN the bundle that is throwing the exception在 Karaf OSGI 中,我得到 ClassNotFoundException 的类是在抛出异常的包中
【发布时间】:2013-07-29 22:27:00
【问题描述】:

背景:在 karaf,我有两个功能,每个功能都使用不同版本的 Jersey(1.17 和 2.0)。

它们是相互分离的,没有包可以同时导入它们。

Jersey 1.17 和 2.0 之间的包名称发生了变化(com.sun.jersey vs. 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 的情况下实施他们的解决方法。

【问题讨论】:

    标签: java glassfish osgi classloader apache-karaf


    【解决方案1】:

    哦,当我们想避免使用服务时,我们编织了多么纠结的网络 :-( 这完全是由于 Java 缺少服务注册表造成的。

    我认为您的问题是 jersey 尝试从您的捆绑包中加载,因为它在该捆绑包中找到服务目录。由于您没有这些课程,因此泽西岛正确地拒绝了。

    最初的解决方案是将这些文件放在 jersey 包的 services 目录中,要求您打开该包。如果球衣包导出了实现包(模块化的诅咒,但通常在不理解 OSGi 的代码中完成),即使您不直接使用它们,您也可以在包中导入这些包。

    另一个我没有检查过的替代方法是使用 OSGi hack:片段。您可以为包含 services 目录的球衣包创建一个片段。但是,不确定这是否有效。

    最后但同样重要的是,您可以将球衣代码私下包含在自己的捆绑包中。使用 bnd,这很容易做到。

    【讨论】:

    • 我会先采用最后一个建议并尝试以这种方式解决它(包括您的 WAB 中的所有内容)。之后,我会尝试再次将它与我的 war/wab 分开并重新导入所需的东西。遗憾的是,大多数免费使用的“服务”不提供 OSGi 服务,但是,你可以不要自己做所有的事情。 ;)
    • @Achim:是的,没有更多的捆绑包提供开箱即用的 OSGi 服务,这很糟糕。但是,看到 maven Central 中的捆绑包数量增长的速度非常有希望。
    猜你喜欢
    • 2016-07-27
    • 2016-06-11
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2014-01-06
    • 1970-01-01
    • 2021-08-17
    • 2021-09-13
    相关资源
    最近更新 更多