Thursday, July 24, 2008

So I want to use the JAX-WS RI with JDK 6, so I need the endorsed directory right?

So JDK6u4 comes with JAX-WS RI 2.1.3 so you don't really need to worry about downloading and instally the RI? Right, well there is some slight confusion in that the sun extensions to the JAX-WS standard, for example WSBinding, are repackaged into a different package path for inclusion into the JDK. Any server is going to use the RI version of these classes without the "internal" in the package path.

You can't just add the RI classes to the source path and have it work as the javax.xml.ws.spi.Provider is hard coded to use the "internal" jdk version of the RI. So lets look at the following options:

1. JDK 6_u4

In this case the provider uses the value of the constant javax.xml.ws.spi.Provider.DEFAULT_JAXWSPROVIDER which is "com.sun.xml.internal.ws.spi.ProviderImpl".

2. JDK 6_u4 + JAX-WS RI in endorsed

In this case the provider uses the value of the constant javax.xml.ws.spi.Provider.DEFAULT_JAXWSPROVIDER in endorsed version of the jar which is "com.sun.xml.ws.spi.ProviderImpl".

This is what the RI documentation tells you; but you only need to do this if the RI version doesn't match that of the JDK.

3. JDK 6_u4 + META-INF/services/javax.xml.ws.spi.Provider

If you are using something like weblogic that there will be an entry on the classpath, for example in weblogic.jar, that contains an service entry with the above path. In the weblogic case the first services contains the text "weblogic.wsee.jaxws.spi.WLSProvider". This extends "normal" RI classes so you get the classes you expect.

This does present a workaround if you want the RI; but can't control the endorsed directories (Perhaps with WebStart). You can simply create the service entry on the classpath in your own jars with the "com.sun.xml.ws.spi.ProviderImpl" class as its only content. This will force the external RI implementation to be used.

Finally it is worth saying that there is nothing wrong with using the RI classes in the JDK, I just find it tidier to use the same set of package names in all cases.

2 comments:

Billyd said...

This post seems to apply to my situation, though I'm on newer versions. I have a web service client built with JaxWS RI 2.1 (not 2.1.3), trying to run it under WebLogic 10.3.3 and it is crashing with:
com.sun.xml.ws.util.ServiceConfigurationError: com.sun.xml.ws.api.client.ServiceInterceptorFactory: Provider weblogic.wsee.jaxws.spi.WLSServiceInterceptorFactory could not be instantiated: java.lang.ClassCastException


So it seems like Gerard's #3 applies. I have 3 choices:
1- use endorsed jars in the jdk (we are on Sun 1.6.0_24)
2- "create the service entry on the classpath in your own jars with the "com.sun.xml.ws.spi.ProviderImpl" - but I don't know how to do that.
3- find a version of the JaxWs that matches the WebLogic one.

Thanks for the post!

Gerard Davison said...

Bill,

Can you give a bit more information about how you are configuring your client, generally replacing the version of JAX-WS in the service is going to end badly. :-)

Gerard