Friday, September 19, 2008

JAX-WS web service and JBoss

Yesterday I wrote an entry about building JAX-WS web service. So thought about testing them on latest versions of JBoss. I chose 4.2.3 and 5.0.0 CR2 (released yesterday), both with Java 6.

JBoss 4.2.3
The deployment of web service failed with following error-

Error configuring application listener of class com.sun.xml.ws.transport.http.servlet.WSServletContextListener
java.lang.ClassNotFoundException: com.sun.xml.ws.transport.http.servlet.WSServletContextListener


which looks quite natural as JBoss has its own implementation of JAX-WS, so it does not have the RI classes. After bundling RI jars with application deployment was error free. I created a small standalone program to invoke the web service, which succeeded without any errors.

What about if web service consumer is also a web application? To test this scenario I created a small web application to consume the above-mentioned service and deployed on JBoss. On invoking web service the following exception was thrown-

org.jboss.ws.metadata.wsdl.WSDLException: Invalid default namespace: null

I thought that by bundling JAX-WS jars with the application, I can overcome this error. But faced another exception-
com.sun.xml.ws.client.WSServiceDelegate cannot be cast to javax.xml.ws.spi.ServiceDelegate21

Now I started scratching my head :-/ When in difficulty the developer community takes help of Google, but here Google did not gave clues. After investigating the JBoss directory structure and their contents I discovered an endorsed directory at ‘jboss-4.2.3.GA\lib\endorsed’ location. Then I deleted all jars (related to JAXB, JAXWS and JAAS) from there except the following ones-
  • Serializer.jar
  • Xalan.jar
  • xercesImpl.jar
and copied JAX-WS RI jars here. Now everything worked even no need to bundle the JAX-WS jars with the applications.

JBoss 5 RC2
Making the web service work on this version of the JBoss also required same steps as with 4.2.3 and service was consumed by a standalone application without any hiccups. Then tried to consume the service using same web application as used for 4.2.3 and with JBoss 5 also it failed with similar error on trying to invoke a service method-

org.jboss.ws.metadata.wsdl.WSDLException: Invalid default namespace: null

On bundling JAX-WS RI jars with the consumer application everything worked fine, so no more ClassCastException or using the endorsed directory mechanism. This is a good improvement over previous versions of JBoss.

40 Comments:

Anonymous said...

Hello, thanks for this detailed and interesting posts. Unfortunately i got some problems, while trying to code what you did.

While the simple HelloWorld-WebService runs well in Tomcat, i also tried to deploy it on JBoss 4.2.3 and 5.0.0CR. I also get the ClassNotFoundException that you have described above. Then i bundled my freshly downloaded Metro-libs (5 pieces) into the WAR (WAR/WEB-INF/lib) and deployed again, getting always this ERROR:

14:54:00,015 ERROR [STDERR] 23.10.2008 14:54:00 com.sun.xml.ws.transport.http.servlet.WSServletContextListener contextInitialized
INFO: WSSERVLET12: JAX-WS context listener initializing
14:54:01,343 ERROR [STDERR] 23.10.2008 14:54:01 com.sun.xml.ws.transport.http.servlet.WSServletDelegate [init]
INFO: WSSERVLET14: JAX-WS servlet initializing

Haven't you encountered this problem as well?

Thx in advance for your help!

Anonymous said...

I was having exactly the same problem with JBoss 4.2.3, your post has saved me lots of time :D

Anonymous said...

I also saw these messages on the console but it does not stop the application from functioning.

Anonymous said...

Thanks for the post. I was having the same problem as you and you saved me a lot of time. Are the "RI jars" that you are referring to the ones located at https://jax-ws.dev.java.net/? I put the jars in the /lib/endorsed directory like you mentioned and replaced the ones that existed (except resolver.jar) and I got Jboss 5 to run the JAX-WS RI service but the server log still shows both error messages you have listed. This makes me uneasy as I am trying to develop a new production environment.

Thanks in advance.

Anonymous said...

ebill,

Yes, by "RI jars" I am referring to the ones downloaded from https://jax-ws.dev.java.net/

Anurag Bangalore said...

Vinod,

I have followed your blog and able to deploy the webservices on Jboss5.0 + jdk1.6_11. But when I am trying to invoke the webservices from the standalone client I am getting this error at jboss server.
I tried to google it but could't find any solution.

17:02:50,468 ERROR [STDERR] Mar 31, 2009 5:02:46 PM com.sun.xml.ws.transport.http.servlet.WSServletDelegate doPost
SEVERE: caught throwable
java.lang.ExceptionInInitializerError
at com.sun.xml.ws.util.SOAPConnectionUtil.getSOAPMessage(SOAPConnectionUtil.java:76)
at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher.getSOAPMessage(SOAPMessageDispatcher.java:227)
at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher.receive(SOAPMessageDispatcher.java:101)
at com.sun.xml.ws.server.Tie.handle(Tie.java:88)
at com.sun.xml.ws.transport.http.servlet.WSServletDelegate.handle(WSServletDelegate.java:333)
at com.sun.xml.ws.transport.http.servlet.WSServletDelegate.doPost(WSServletDelegate.java:288)
at com.sun.xml.ws.transport.http.servlet.WSServlet.doPost(WSServlet.java:77)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:828)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:601)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
Caused by: Couldn't create SOAP message factory due to exception: javax.xml.soap.SOAPException: Unable to create SAAJ meta-factoryorg.jboss.ws.core.so
ap.SAAJMetaFactoryImpl cannot be cast to javax.xml.soap.SAAJMetaFactory
at com.sun.xml.ws.util.SOAPUtil.createMessageFactory(SOAPUtil.java:176)
at com.sun.xml.ws.util.SOAPUtil.clinit(SOAPUtil.java:43)
... 29 more
Caused by: javax.xml.soap.SOAPException: Unable to create SAAJ meta-factoryorg.jboss.ws.core.soap.SAAJMetaFactoryImpl cannot be cast to javax.xml.soap
.SAAJMetaFactory
at javax.xml.soap.SAAJMetaFactory.getInstance(Unknown Source)
at javax.xml.soap.MessageFactory.newInstance(Unknown Source)
at com.sun.xml.ws.util.SOAPUtil.createMessageFactory(SOAPUtil.java:174)
... 30 more

Anonymous said...

Anurag,

Did you tried the source code available here?

Guillaume Morin-B. said...

I did all those steps on JBoss 4.2.3 and after some tries it seemed that there was some problems with the HttpServlet class that was not found for some reasons I don't know.

So I started looking for some other solutions and I found an easier solution which is to simply change the servlet-class implementation from com.sun.xml.ws.transport.http.servlet.WSServlet to the name of my own web service imlpementation class. Then everything started to work fine and i did not even need to modify any jars nor export any jars with my application. Hope this will help people save some time :)

See: http://www.netbeans.org/kb/55/websvc-jaxws-jboss.html#Exercise_1_2

Guillaume Morin-B. said...

By the way, I tried that with my own web project so that's probably why I had this HttpServlet error. You probably won't have this error with your sample project.

Also, I forgot to mention to take of the listener class in the web.xml file.

Unknown said...

Thanks for the blog. It helped me solve the problem in Tomcat5.5.

Jack said...

But isn't copying files into endorsed considered bad practice?

Please don't misunderstand me, I'm just confused.

Anonymous said...

Jack,

Yes, endorsed directory mechanism is just a workaround. This was required in earlier updates of Java 6, which were packaging older versions of JAX-WS. With recent updates of Java 6, this is no longer required.

Uday Kumar said...

hi vinod, i tried to do simple jax-ws webservice in jboss 5.

I tried the way you said. I copied the jax-ri jar files in to endoresed/lib and also i packed those jars in side the war file. After deploying the war file in jboss5, it is giving error like....


INFO: WSSERVLET12: JAX-WS context listener initializing
18:43:47,029 ERROR [STDERR] Oct 23, 2009 6:43:47 PM com.sun.xml.ws.transport.http.servlet.WSServletDelegate init
INFO: WSSERVLET14: JAX-WS servlet initializing
18:43:47,029 INFO [[/SampleJAX_WS]] Marking servlet MyServiceImpl as unavailable
18:43:47,029 ERROR [[/SampleJAX_WS]] Servlet /SampleJAX_WS threw load() exception
java.lang.ClassCastException: com.MyServiceImpl cannot be cast to javax.servlet.Servlet


Please help me in this.

Thanks in advance....

Anonymous said...

Uday,

Can you please try with the source code available here.

Uday Kumar said...

I tried with the same code and adding the jax-ws ri jars in the lib of war file as well as server's lib. But no use.

I don't know where the things are going wrong.

Please help me in this.

java.lang.ClassCastException: com.MyServiceImpl cannot be cast to javax.servlet.Servlet
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1006)

above was the error.

Uday Kumar said...

Hi vinod,

i'ma able to deploy simple jax-ws in jboss with your help.

I'm trying to return an object(here a list object)from webservice. When i tried to do this it is giving error like below
.......

12:39:11,796 ERROR [STDERR] Oct 30, 2009 12:39:11 PM com.sun.xml.ws.transport.ht
tp.servlet.WSServletDelegate doGet
SEVERE: caught throwable
javax.xml.ws.WebServiceException: javax.xml.bind.MarshalException
- with linked exception:

[javax.xml.bind.JAXBException: class [Ljava.lang.Object; nor any of its super class is known to this context.]
at com.sun.xml.ws.message.jaxb.JAXBMessage.writePayloadTo(JAXBMessage.ja
va:322)
at com.sun.xml.ws.message.AbstractMessageImpl.writeTo(AbstractMessageImp
l.java:142)
at com.sun.xml.ws.encoding.StreamSOAPCodec.encode(StreamSOAPCodec.java:1
08)
at com.sun.xml.ws.encoding.SOAPBindingCodec.encode(SOAPBindingCodec.java
:258)
at com.sun.xml.ws.transport.http.HttpAdapter.encodePacket(HttpAdapter.ja
va:320)
at com.sun.xml.ws.transport.http.HttpAdapter.access$100(HttpAdapter.java
:93)
at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdap
ter.java:454)
at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:244
)
at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAd
apter.java:135)
at com.sun.xml.ws.transport.http.servlet.WSServletDelegate.doGet(WSServl
etDelegate.java:129)
at com.sun.xml.ws.transport.http.servlet.WSServletDelegate.doPost(WSServ
letDelegate.java:160)
at com.sun.xml.ws.transport.http.servlet.WSServlet.doPost(WSServlet.java
:75)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
icationFilterChain.java:290)

Anonymous said...

@Uday,

java.lang.Object is not allowed to be exposed as web service input/output. See the list of java data types allowed to use in web service interface here http://java.sun.com/javaee/5/docs/tutorial/doc/bnazq.html

See if this post AnyType object over webservice and Hibernate helps you in any way.

Anonymous said...

Helle, are you aware that this is totally unsupported.
The reason why Serializer.jar, Xalan.jar and xercesImpl.jar are in the jboss-4.2.3.GA\lib\endorsed directory is because java 6 breaks the webservices stack that is already part of JBoss. You cannot mix two implementations of JAX-WS in the same application server.
You basically have two options. Remove JAX-WS from your application and start using the JAX-WS stack that is part of JBoss. There is some documentation on how to do spring websevices with weblogic on the the Oracle web site.
Or stop using a JEE server and use Tomcat or some Tomcat derivative like Spring DM Server or JBossWeb to deploy your application.

Anonymous said...

Hello, I'm adding to my previous post.
First of all Serializer.jar, Xalan.jar and xercesImpl.jar have always been in the endorsed directory. To run JBoss on java 6 you have to add jboss-jaxrpc.jar jboss-jaxws.jar jboss-saaj.jar to the endorsed directory as well. See http://www.redhat.com/docs/en-US/JBoss_Enterprise_Application_Platform/4.3.0.cp06/html-single/JDK6_Compatibility_Notes/index.html.
A good starting point for Spring and JEE integration can be found on the Spring website http://static.springsource.org/spring/docs/2.5.x/reference/remoting.html chapter 17.5.5. Exposing servlet-based web services using JAX-WS.
Some JEE application servers have features that make Spring integration a little easier, Apache Geronimo's CXF is actually Spring based and Glassfishes Metro has RI see https://jax-ws-commons.dev.java.net/spring/.
You can use both of these web service stacks with JBoss, but you can only do this using the JBoss distributions of the web service stacks. For more information on this see http://www.jboss.org/jbossws.

Anonymous said...

The above what were you said was good, after doing all the configuration, I facing the problem


java.lang.NoClassDefFoundError: org/jboss/logging/Logger

plz do needfull.

Anonymous said...

This seems to be a class path issue. See if you can provide some information about versions of Java, JBoss etc. and full stack trace.

Anonymous said...

java.lang.NoClassDefFoundError: javax/xml/ws/spi/ServiceDelegate21

I am getting above exception in Jboss application server. Calling JAX-WS client in servlet.

can you help me

kara.cuma said...

hi,

I'm using jboss 5.1.0.GA and metro 2.0.
when i was deploying my application(ear) which includes web service implementations, i get error "org.xml.sax.SAXParseException: Anonymous types form an infinite cycle".

when i was creating web service artifacts,
(wsimport -XadditionalHeaders -B-XautoNameResolution -keep -d . -p biz.x.x myservice.wsdl -b _v4.xsd).

what can i do?


Caused by: java.io.IOException: Failed to generate schema.
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.generateSchema(JAXBContextImpl.java:840)
at org.jboss.ws.tools.wsdl.JAXBWSDLGenerator.processTypes(JAXBWSDLGenerator.java:74)
... 42 more
Caused by: org.xml.sax.SAXParseException: Anonymous types form an infinite cycle: ClassInfo(class biz.xx.A) -> ClassInfo(class biz.xx.A)
at com.sun.xml.bind.v2.schemagen.XmlSchemaGenerator$Namespace.writeTypeRef(XmlSchemaGenerator.java:769)
at com.sun.xml.bind.v2.schemagen.XmlSchemaGenerator$Namespace.writeTypeRef(XmlSchemaGenerator.java:748)
at com.sun.xml.bind.v2.schemagen.XmlSchemaGenerator$Namespace.access$1700(XmlSchemaGenerator.java:493)
at com.sun.xml.bind.v2.schemagen.XmlSchemaGenerator$Namespace$2.write(XmlSchemaGenerator.java:1029)
at com.sun.xml.bind.v2.schemagen.Tree$Optional.write(Tree.java:181)
at com.sun.xml.bind.v2.schemagen.Tree$Repeated.write(Tree.java:207)

Anonymous said...

@kara.cuma

The error message org.xml.sax.SAXParseException: Anonymous types form an infinite cycle gives an impression that the WSDL has some incorrect relationship among various objects leading to cyclic dependency. A deeper look at the WSDL may reveal the exact cause of this error.

kara.cuma said...

thanks for quick reply. I found it.
One object contains list of itself.
I tried to put their own annotation (XmlElement) and its work.

Anonymous said...

Hi Vinod,

Your blog is a good start for me. However, I get some kind of
I tired to run the sample application on Jboss 5.1.0.GA, JDK 6.

Here is the log when it deploys in the server.

16:43:28,352 INFO [http] WSSERVLET12: JAX-WS context listener initializing
16:43:28,633 SEVERE [http] WSSERVLET11: failed to parse runtime descriptor: java.lang.LinkageError: loader constraint violation: when resolving field "DATETIME" the class loader (instance of org/jboss/classloader/spi/base/BaseClassLoader) of the referring class, javax/xml/datatype/DatatypeConstants, and the class loader (instance of ) for the field's resolved type, javax/xml/namespace/QName, have different Class objects for that type
java.lang.LinkageError: loader constraint violation: when resolving field "DATETIME" the class loader (instance of org/jboss/classloader/spi/base/BaseClassLoader) of the referring class, javax/xml/datatype/DatatypeConstants, and the class loader (instance of ) for the field's resolved type, javax/xml/namespace/QName, have different Class objects for that type
at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl.(RuntimeBuiltinLeafInfoImpl.java:224)
at com.sun.xml.bind.v2.model.impl.RuntimeTypeInfoSetImpl.(RuntimeTypeInfoSetImpl.java:61)

Here is my pom.xml
<plugins>

<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>wsgen</goal>
</goals>
</execution>
</executions>
<configuration>
<sei>pkg.MyServiceImpl</sei>
<resourceDestDir>${basedir}/WebRoot/WEB-INF</resourceDestDir>
<genWsdl>true</genWsdl>
<keep>true</keep>
<verbose>true</verbose>
</configuration>
<dependencies>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.2</version>
<scope>compile</scope>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>javaee-api</artifactId>
<version>5.0-1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.1-1</version>
</dependency>

Am I missing something here on JBoss? I am able to deploy it under tomcat 6.0.18.

Thanks....

Anonymous said...

This seems to be class collision issue. Some jars available in your application's WEB-INF/lib diretory may be present in JBoss' classpath as well, which is not the case with Tomcat. Try to findout such jars and remove them from your application.

Anonymous said...

Thanks Vinod. Sweet. That really helped.

If I were to package these service classes and resources under jar file....
Where should the resources like wsdl files and sun-jaxws should be placed. Should they go under META-INF folder?
And, Since jar file does not have a context, how will I be able to reference the wsdl from my clients or web apps.


Thanks.

Anonymous said...

Service classes can be packaged in a jar under WEB-INF/lib or put them inside WEB-INF/classes directory. sun-jaxws.xml should go under WEB-INF and WSDL will be generated at runtime. For accessing web service from other applications you need to generate web service client using 'wsimport' goal of 'jaxws-maven-plugin' plugin.

Travisa said...

Thanks very much. I've been looking for the solution for a while and it finally worked!

Anonymous said...

Thanks Vinod. That helped. I am able to package services in jar and reference them in my web archive.

Thanks..

Samuli said...

Thanks for the post. Got my WS client working on JBAS 4.2.3 with this!

Tuno said...

For classloading issues try using ClassLoadingMetaData:
http://java.dzone.com/articles/jboss-microcontainer-classloading?mz=3006-jboss

Anonymous said...

Thanks a lot for this Post. This ugly Error took 1 day to fix :(

Andre said...

I dont understand how to use the RI files. Can you please help me?

Vinod Singh said...

@Andre,

RI jars can be used by including them in WEB-INF\lib directory.

Anonymous said...

Thanks Vinod !

Your blog helped me in a great way !

Java OutOfMemoryError said...

What makes it even more painful is that programmer often confused this with NoClassDefFoundError in Java which is completely different and drives debugging into different path. if you know more on difference check out ClassNotFoundException vs NoClassDefFoundError.

Carlo said...

Even if your post is very old, it's still very useful. Thanks.

Anonymous said...

Please help:-
i m able to make client but I got exception when deploying it ,
java.lang.ClassCastException: $Proxy91 cannot be cast to com.sun.xml.ws.developer.WSBindingProvider