Eclipse RCP classloading problem with Metro
I am attempting to invoke a web service using the Metro library 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.<init>(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: 2009092开发者_如何学运维0-1017 (it doesn't display a version beyond that)
Metro version: Bundled with Glassfish 2.1
Any help is greatly appreciated. Thanks.
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.
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.
精彩评论