views:

556

answers:

2

Hello,

I am attempting to invoke a web service using the Metro library (https://metro.dev.java.net/) from within an Eclipse RCP application. I bundled the relevant Metro jars (webservices-tools.jar, webservices-rt.jar, and webservices-api.jar) into a plugin and made my main application plugin depend on this new Metro plugin.

I also added the webservices-api.jar to my $JAVA_HOME/jre/lib/endorsed directory. According to the Metro website, this is required when using Metro with Java 1.6.

Now when I invoke any web service, I get the following error:

javax.xml.ws.WebServiceException: Provider com.sun.xml.ws.spi.ProviderImpl not found at javax.xml.ws.spi.FactoryFinder.newInstance(FactoryFinder.jav a:38) at javax.xml.ws.spi.FactoryFinder.find(FactoryFinder.java:133) at javax.xml.ws.spi.Provider.provider(Provider.java:83) at javax.xml.ws.Service.(Service.java:56)
...
Caused by: java.lang.ClassNotFoundException: com.sun.xml.ws.spi.ProviderImpl at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301 ) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at org.eclipse.core.runtime.internal.adaptor.ContextFinder.load Class(ContextFinder.java:129) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at javax.xml.ws.spi.FactoryFinder.newInstance(FactoryFinder.jav a:34) ... 43 more

The class com.sun.xml.ws.spi.ProviderImpl resides in webservices-rt.jar, which is a part of my Metro plugin. Furthermore, I have verified that my application plugin code can successfully load this class, so I'm not sure why javax.xml.ws.spi.FactoryFinder can't.

Since javax.xml.ws.spi.FactoryFinder resides in webservices-api.jar (the jar I had to put in the jre's endorsed directory), I suspect that this has something to do with endorsed code not being able to load classes from an Eclipse plugin.

Is it the case that code loaded by the JVM from the endorsed directory cannot load classes from plugins? Is there any way to enable this?

Java version: 1.6.0_16 Eclipse version: Eclipse Java EE IDE for Web Developers Build id: 20090920-1017 (it doesn't display a version beyond that) Metro version: Bundled with Glassfish 2.1

Any help is greatly appreciated.

Thanks,
-Jeff

A: 

Java SE 6 already includes metro. It includes jax-ws 2.0, so you can remove those jars completely.

Only if you have specific need to use jax-ws 2.1 together with java SE 6, you can follow the instructions here -> https://jax-ws.dev.java.net/faq/index.html

EDIT: You are right about your last comment. Code placed in the endorsed folder is loaded with the endorsed class loader, so it can't find classes that are located in the plugins. I suggest that you put the all the metro jars in the endorsed dir. This way they'll be available not only for your plug-in, but for the entire VM.

Yoni
The problem is that the Java SE 6 version of JAX-WS does not implement security. I have tried removing the metro jars as you suggest, in which case I get past the error above but then I get an error back from the server complaining that my client did not include a security header (confirming that the JDK version of JAX-WS does not implement security).So I think I really need to use the Metro version of JAX-WS in order to implement security.
Jeff
are you sure about the lack of security? The guide clearly says "Java SE 6 Update Release 4 and later already contain the JAX-WS 2.1 API and the following work around is not necessary anymore"
Yoni
Regarding your edit, the Metro site explicitly states that _only_ the webservices-api.jar should go into the endorsed directory, and none of the other jars. Nevertheless, I did try putting the other metro jars in the endorsed directory. When I do, I start getting strange LinkageErrors. Regarding the lack of security, I read that in another online forum. That doesn't mean it's true of course, but when I attempt to run without any metro jars, the client runs but does not include a security header in the request (confirmed by the error returned from the server and tcpmon).
Jeff
A: 

For anyone else who runs into this problem, I was able to find a solution. I added the metro jars, along with the config directory containing my wsit configuration files, to the JVM's boot classpath using these JVM options:

-Xbootclasspath/a:./lib/webservices-api.jar -Xbootclasspath/a:./lib/webservices-rt.jar -Xbootclasspath/a:./lib/webservices-tools.jar -Xbootclasspath/a:./config

The webservices-api.jar no longer needs to be in $JAVA_HOME/jre/lib/endorsed for this to work. It is certainly not the normal Eclipse model, but this is the only way I have found to use Metro within an Eclipse RCP application with Java 1.6.

-Jeff

Jeff