我的任务是将生物可视化软件平台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.extra
和org.osgi.framework.bootdelegation
属性,但无济于事。但是,我有可能做错了。
我担心OSGI可能与用于创建该标头的Reflection API有一些基本的不兼容性。但肯定在这种环境下运行Web服务客户端是不可能的,对吧?
答案 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.*