Monday, October 3, 2011

Developing WebServices using JDK6/JAX-WS is simple. Is it true?

In many articles, blogs we can see how to develop WebServices using with JDK6's JAX-WS in-built support in just 5 minutes.

We can simply write a POJO and annotate it with @WebService, publish it with Endpoint.publish(...) and you can see the generated wsdl by pointing your browser to http://localhost:8080/JAXWS/helloService?wsdl.

Immediately we can write a client and call helloPort.sayHello("siva") and you will get "Hello Siva!!!" response from your HelloWebService.

In the first look it feels like developing web services is very simple using JDK6's in-built JAX-WS support.

With that confidence immediately I thought of writing a bit more complex WebService and deploy it on Tomcat.

As we can find number of articles on how to develop/deploy JAX-WS webservices on Tomcat Server, I started writing my next ABitComplexService and deployed on Tomcat and saw the generated WSDL file.

Then I generated client stubs using wsimport and invoked webservice methods and it worked fine... :-)

Then I though of invoking the webservice from a simple web project and put the client code in a new Web web project and and call the web service.

Now the show begins :-)

Then I got an opportunity to know what is JDK's endorsed directory, how App Servers have their specific endorsed directories etc etc.

I got weird errors like:

Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: javax.xml.ws.WebFault.messageName()Ljava/lang/String;

java.lang.ClassCastException: com.sun.xml.bind.v2.runtime.JAXBContextImpl cannot be cast to com.sun.xml.bind.api.JAXBRIContext

After struggling for sometime I copied jaxws-api.jar/jaxb-api.jar to endorsed directories and finally get it worked.


Now I wanted to make it a bit more complicated and thought of creating another WebService and deploy on JBoss Server and call it from the first WebService deployed on Tomcat.

Now I have:

1. MySecondWS webservice deployed on JBoss.
2. MyFirstWS webservice deployed on Tomcat. It is a Service Provider and Consumer(for MySecondWS) as well.
3. MyWebClient a Dynamic Web Project. Its a client for MyFirstWS.

Here as MyFirstWS webservice is a Service provider I have all the JAX-WS RI jars in WEB-INF/lib directory.

All set and I deployed all the Apps on their servers and hit the Submit button triggering MyFirstWS webservice call().

I got weird errors like NullPointerExceptions, MetadataModelExceptions etc.

After some trials I have identified the pattern that if I invoke the client from a project which has JAXWS-RI jars in its classpath I am getting this error.

But I need to develop a WebService which is both Service Provider and Consumer...
For the Service Producer I need to have those Jars in my classpath and at the same time to be Service Consumer I shouldn't have those jars in my WEB-INF/lib.

So what to do? Yes, I know I need some more time to Google and I can find a way how to do this as this is very common requirement. But I feel like Developing Web Services using JDK6's JAX-WS in-build support is not as easy as Advertised(My opinion only).

Anyway this weekend I understood two things:
1. Developing (Real)WebServices with JAX-WS is not that simple as advertised in the Articles/Blogs.
2. You can easily waste your week-ends by entering into Java-Jar-Hell :-)

3 comments:

  1. Hello
    Welcome to JavaEE! :)

    Could you believe that using JAX-WS with CXF in your WEB-INF/lib requires deleting JBOSS6/lib/endorsed/jbossws-cxf-factories.jar?

    If you want to use JBoss - use JBoss 7 - it's really fast and JBossModules seems to be *the* solution for JAR/Endorsed/Ext/ParentCL hell

    regards
    Grzegorz Grzybek

    ReplyDelete
  2. There are certainly a lot more details to take into consideration, but thanks for sharing this post.
    source: www.wbupdates.com

    ReplyDelete
  3. Did you ever resolve this? I'm having a very similar error and have wasted lots of time trying to figure it out. If I have the webservices-* jars in my classpath, I can host web services but not consume. If I don't have webservices-* in my classpath, I can consume web services but not host. Beyond frustrating!

    ReplyDelete