【问题标题】:NoClassDefFoundError when using JAX-WS in an OSGI 4.2 bundle在 OSGI 4.2 包中使用 JAX-WS 时出现 NoClassDefFoundError
【发布时间】:2014-02-10 23:16:50
【问题描述】:

我的任务是将生物可视化软件平台 Cytoscape 的插件更新到最新版本的 Cytoscape API。 Cytoscape 3.x 使用 OSGI 框架(我认为是 Karaf 2.2.x)与其插件(现在称为“应用程序”)交互。

问题在于插件/应用程序使用JAX-WS与外部服务器通信,而JAX-WS在OSGI环境中加载类似乎有问题。

这是有问题的代码的sn-p:

public class AnatServerService extends Service {
    @WebEndpoint(name = "AnatServerPort")
    public AnatServerIfc getServerPort() {
        AnatServerIfc port =  super.getPort(new QName("network", "AnatServerPort"), AnatServerIfc.class);
        ((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, path);
    return port;
    }
}

这是导致的异常:

java.lang.NoClassDefFoundError: com.sun.xml.internal.ws.api.message.Header not found by AnatApp [168]
    at com.sun.proxy.$Proxy64.<clinit>(Unknown Source)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at java.lang.reflect.Proxy.newInstance(Unknown Source)
    at java.lang.reflect.Proxy.newProxyInstance(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.createProxy(UnknownSource)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.createEndpointIFBaseProxy(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(Unknown Source)
    at javax.xml.ws.Service.getPort(Unknown Source)
    at anat.ws.AnatServerService.getServerPort(AnatServerService.java:36)
    at anat.task.AvailableNetworksTask.getAvailableNetworks(AvailableNetworksTask.java:39)
    at anat.task.AvailableNetworksTask.run(AvailableNetworksTask.java:62)
    at org.cytoscape.work.internal.sync.SyncTaskManager.execute(SyncTaskManager.java:86)
    at anat.view.BackgroundDefinitionDialog$AvailableNetworksSwingWorker.doInBackground(BackgroundDefinitionDialog.java:1544)
    at anat.view.BackgroundDefinitionDialog$AvailableNetworksSwingWorker.doInBackground(BackgroundDefinitionDialog.java:1535)
    at javax.swing.SwingWorker$1.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at javax.swing.SwingWorker.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

我可以确认此代码确实在 OSGI 之外工作。

有什么建议吗?我尝试过使用Embed-Dependency 将 JAX-WS API 和/或实现类直接嵌入到包中,但这没有帮助。我也尝试过使用org.osgi.framework.system.packages.extraorg.osgi.framework.bootdelegation 属性,但无济于事。不过,我可能做错了什么。

我担心 OSGI 可能与用于创建该标头的反射 API 存在一些根本不兼容。但是在这种环境下运行 Web 服务客户端肯定是不可能的吧?

【问题讨论】:

    标签: java osgi jax-ws cytoscape karaf


    【解决方案1】:

    似乎 JAX-WS 正在将构建时不存在的依赖项动态编织到您的包中。由于这些依赖项是动态的,因此构建工具不会找到它们,也不会为它们生成 Import-Package 语句。

    具体来说,您的包依赖于包com.sun.xml.internal.ws.api.message。您从未想要或要求过这种依赖关系,但 JAX-WS 还是为您添加了它。多好啊!

    您的问题表明您正在使用 Maven 和 maven-bundle-plugin 来构建您的捆绑包。因此,您需要在您的 pom 中添加类似这样的内容:

    <Import-Package>
        com.sun.xml.internal.ws.api.message,
        *
    </Import-Package>
    

    请注意,可能还有其他软件包需要添加到此列表中……您可能会在添加此软件包后发现它们。同样,由于这些是动态编织的依赖项,因此不可能提前获得它们的完整列表。

    关于你的最后一个问题。没错,在这种环境下运行 Web 服务客户端肯定不是不可能的!然而,OSGi 确实倾向于暴露无效的假设和错误的编码实践,这些通常存在于像 JAX-WS 这样的蹩脚库中。

    【讨论】:

    • 哦,是的,我想我也尝试过使用Import-Package,但我很快就把它搁置了。我可能应该尝试更多。结果如下:org.osgi.framework.BundleException: Unresolved constraint in bundle AnatApp [168]: Unable to resolve 168.4: missing requirement [168.4] package; (package=com.sun.xml.internal.ws.api.message) 也许我需要将这种方法与我已经尝试过的方法之一结合起来。
    • 原来Import-Package 不是必需的。看我的回答。
    【解决方案2】:

    我已经解决了我自己的问题。事实证明,我在错误的文件中编辑了 org.osgi.framework.bootdelegation 属性 - config.properties 而不是 custom.properties

    不过,从长远来看,这仍然是一个问题。我希望能够分发此捆绑包,而无需用户编辑配置文件。

    【讨论】:

    【解决方案3】:

    我遇到了同样的问题。将以下行添加到 Felix 的 config.properties 文件中解决了这个问题:

    org.osgi.framework.bootdelegation=com.sun.xml.internal.ws.*
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-13
      • 1970-01-01
      • 2012-06-12
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 1970-01-01
      相关资源
      最近更新 更多