在OSGI 4.2包中使用JAX-WS时出现NoClassDefFoundError

时间:2014-02-10 23:16:50

标签: java osgi jax-ws cytoscape karaf

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

问题是插件/ app使用JAX-WS与外部服务器通信,而JAX-WS似乎在OSGI环境中加载类时遇到问题。

以下是有问题的代码片段:

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可能与用于创建该标头的Reflection API有一些基本的不兼容性。但肯定在这种环境下运行Web服务客户端是不可能的,对吧?

3 个答案:

答案 0 :(得分:0)

似乎JAX-WS动态地将依赖项编织到您的bundle中,这些依赖项在构建时不存在。由于这些依赖项是动态的,因此构建工具不会找到它们,也不会为它们生成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这样糟糕的库中发现的无效假设和错误的编码实践。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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