質問

I've been tasked with updating a plugin for Cytoscape, a biological visualization software platform, to the latest version of the Cytoscape API. Cytoscape 3.x uses an OSGI framework (Karaf 2.2.x, I think) to interface with its plugins (which are now called "apps").

The problem is that the plugin/app uses JAX-WS to communicate with an external server, and JAX-WS seems to have problems with loading classes in the OSGI environment.

Here is a snippet of the problematic code:

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;
    }
}

And here is the resulting exception:

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)

I can confirm that this code does work outside of OSGI.

Any suggestions? I've tried experimenting with embedding the JAX-WS API and/or implementation classes directly into the bundle using Embed-Dependency, but that didn't help. I've also tried playing with the org.osgi.framework.system.packages.extra and org.osgi.framework.bootdelegation properties, to no avail. It is possible that I'm doing something wrong, though.

I'm afraid that OSGI might have some fundamental incompatibility with the Reflection API being used to create that header. But surely it can't be impossible to run a web service client in this environment, right?

役に立ちましたか?

解決 2

I've solved my own problem. It turns out I had edited the org.osgi.framework.bootdelegation property in the wrong file - config.properties instead of custom.properties.

This is still a problem in the long term, though. I'd like to be able to distribute this bundle without requiring users to edit config files.

他のヒント

It seems like JAX-WS is dynamically weaving dependencies into your bundle that were not present at build time. Because these dependencies are dynamic, the build tooling doesn't find them and doesn't generate an Import-Package statement for them.

Specifically your bundle has a dependency on the package com.sun.xml.internal.ws.api.message. You never wanted or asked for that dependency, but JAX-WS added it for you anyway. How nice of it!

Your question suggests that you are using Maven with the maven-bundle-plugin to build your bundle. Therefore you need to add something like this to your pom:

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

Note that there may be other packages that need to be added to this list... you will probably find out about them after adding this one. Again, because these are dynamically weaved-in dependencies it's impossible to get a full list of them in advance.

With regard to your final question. You're right, it's certainly not impossible to run a web service client in this environment! However OSGi does tend to expose the invalid assumptions and bad coding practices that are typically found in crappy libraries like JAX-WS.

I had the same problem. Adding the following line to Felix's config.properties file solved the problem:

org.osgi.framework.bootdelegation=com.sun.xml.internal.ws.*
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top