1

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

问题在于插件/应用程序使用 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 之外确实有效。

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

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

4

3 回答 3

0

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

具体来说,您的 bundle 依赖于 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 等蹩脚库中发现的无效假设和糟糕的编码实践。

于 2014-02-11T01:34:31.293 回答
0

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

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

于 2014-02-11T10:02:46.410 回答
0

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

org.osgi.framework.bootdelegation=com.sun.xml.internal.ws.*
于 2014-08-11T10:23:51.887 回答