【问题标题】:NoClassDefFoundError in OSGi bundle on accessing standard java classes访问标准 java 类时 OSGi 包中的 NoClassDefFoundError
【发布时间】:2014-04-05 23:10:15
【问题描述】:

我正在尝试从我的主应用程序访问 OSGI 包。但是,如果访问使用 javax.xml.* 包的捆绑包中的类。抛出 NoClassDefFoundError。

java.lang.NoClassDefFoundError: javax/xml/transform/Source
    at de.foo.bar.test.Builder.<init>(Builder.java:46) ~[test-bundle-1.4.0.jar:1.4.0]
    at de.foo.bar.test.request.Factory.createRequest(Factory.java:99) ~[?:?]
    at de.foo.bar.test.request.Request.prepareRequest(Request.java:93) ~[?:?]
    at de.foo.bar.test.request.Request.process(Request.java:60) ~[?:?]
    at de.foo.bar.test.TestClass.execute(TestClass.java:74) ~[?:?]
    at de.foo.bar.test.TestClass.execute(TestClass.java:1) ~[?:?]
    at de.foo.bar.service.system.OsgiTransactionHandler.handleTransaction(OsgiTransactionHandler.java:71) ~[bin/:?]
    at de.foo.bar.service.system.TransactionRequestService.processTransaction(TransactionRequestService.java:110) ~[bin/:?]
    at de.foo.bar.service.system.TransactionRequestService.runService(TransactionRequestService.java:72) ~[bin/:?]
    at de.foo.bar.service.model.InfiniteService.run(InfiniteService.java:57) ~[bin/:?]
    at com.google.common.util.concurrent.AbstractExecutionThreadService$1$2.run(AbstractExecutionThreadService.java:60) [guava-16.0.1.jar:?]
    at com.google.common.util.concurrent.Callables$3.run(Callables.java:93) [guava-16.0.1.jar:?]
    at java.lang.Thread.run(Thread.java:662) [?:1.6.0_43]
Caused by: java.lang.ClassNotFoundException: javax.xml.transform.Source not found by test-bundle [1]
    at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532) ~[org.apache.felix.framework-4.2.1.jar:?]
    at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75) ~[org.apache.felix.framework-4.2.1.jar:?]
    at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955) ~[org.apache.felix.framework-4.2.1.jar:?]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247) ~[?:1.6.0_43]
    ... 13 more

我在 MANIFEST.MF 中检查了导入的包,可以看到包 javax.xml.transform 被声明(我已经缩短了一点):

Import-Package: com.fasterxml.jackson.core;resolution:=optional,com.fast
 ...
 500;resolution:=optional,javax.servlet;resolution:=optional,javax.sql;r
 esolution:=optional,javax.swing;resolution:=optional,javax.xml.bind;res
 olution:=optional,javax.xml.bind.annotation;resolution:=optional,javax.
 xml.bind.annotation.adapters;resolution:=optional,javax.xml.parsers;res
 olution:=optional,javax.xml.transform;resolution:=optional,javax.xml.tr
 ansform.stream;resolution:=optional,javax.xml.validation;resolution:=op
 tional,org.bson;resolution:=optional,org.lightcouch;resolution:=optiona
 l,org.osgi.framework;resolution:=optional;version="[1.5,2)",org.osgi.fr
 amework.wiring;resolution:=optional,org.w3c.dom;resolution:=optional,or
 g.xml.sax;resolution:=optional,sun.misc;resolution:=optional

我使用4.2.1版本的apache felix作为嵌入式框架,maven-bundle-plugin配置如下:

<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Bundle-Name>Test Bundle</Bundle-Name>
            <Bundle-Activator>de.foo.bar.test.activator.TestActivator</Bundle-Activator>
            <Service-Component>OSGI-INF/component.xml</Service-Component>
            <Export-Package>de.foo.bar.test</Export-Package>
            <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
            <Import-Package>*;resolution:=optional</Import-Package>
            <Embed-Transitive>true</Embed-Transitive>
            <Embed-Dependency>*;scope=compile|runtime;inline=false;artifactId=!org.osgi.core</Embed-Dependency>
            <_failok>true</_failok>
            <_nouses>true</_nouses>
            <_nodefaultversion>true</_nodefaultversion>
            <_snapshot>${osgi-version-qualifier}</_snapshot>
        </instructions>
    </configuration>
</plugin>

我尝试使用 FRAMEWORK_SYSTEMPACKAGES_EXTRA 属性导出丢失的包。但这似乎导致导出所有 Java 包。我已经在第 7 个包裹中停止了它。

有没有办法在不显式导出的情况下提供这些 java 标准包?

【问题讨论】:

  • 有趣的问题。我只能建议您快速浏览一下 jboss,AS7+ 使用 OSGi 来处理所有内容,以及基本包,也许您可​​以看到他们是如何做到的。
  • Equinox 具有标准 JRE 的配置文件,以便系统捆绑包导出典型的包。虽然 Felix 也有类似的机制,但我会希望的。
  • @BJHargrave 您有指向记录这些 Equinox 配置文件的网站的链接吗?
  • 上面的链接是完美的。简而言之,这些包的显式导出不是必需的,甚至可以通过引导委托来避免显式导入。但是,由于您已经有明确的导入,所以您做对了,并且正在发生其他事情。为什么你所有的包导入都是可选的?这是避免 OSGi 的好处并将所有类加载问题推迟到运行时的好方法,旧的 Java 风格,而不是在包启动时快速而明确地失败。

标签: java maven-2 osgi noclassdeffounderror apache-felix


【解决方案1】:

此问题的原因位于框架配置中。根据在线教程,我在配置中添加了以下参数:

config.put(Constants.FRAMEWORK_SYSTEMPACKAGES, "org.osgi.framework; version=1.5.0");

这导致默认系统包被替换,除了我导出的额外包之外,只有org.osgi.framework可用。

在我删除这一行之后,默认包再次可用,因此 javax.xml.transform。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-08
    • 2012-07-22
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 2015-09-05
    • 1970-01-01
    相关资源
    最近更新 更多