Web Services on JBoss
Wednesday, October 29, 2008 21:26I’ve been working on a project which requires developing some web service endpoints. This is the first time I’ve had to develop Java web services and I came across a couple of issues which slowed me down. I am using JBoss 4.0.5.GA which comes packaged with JBossWS 1.0.3.SP1. I started out by going through the examples provided in Chapter 12 of the J2EE Users Guide which helped me get a template for my project. As I attempted to expand my project with multiple service endpoints I received errors during deployment using JBossWS 1.0.3.SP1. I decided to upgrade to JBossWS 1.2.1.GA which is packaged in the 4.2.3.GA certified distribution of JBoss Application Server. The upgrade solved some of my initial issues but introduced a couple more, some of which are not documented in the official JBossWS users guide.
It’s been a frustrating experience so far. I’ve spent the past week troubleshooting and prototyping various web service implementations with different versions of JBossWS rather than developing my application code. The issues have revolved primarily around different versions of JBossWS and deployment. For instance, I found that I could successfully deploy multiple web service endpoints configured as servlets on JBossWS 1.2.0.SP1 which I could not do in 1.0.3.SP1. That being fixed my next task was to refactor the code as EJB service endpoints. Prior to doing that I decided to upgrade JBossWS to version 1.2.1.GA. Logically it is a minor upgrade 1.2.0 to 1.2.1 and should just contain minor bug fixes. However, after upgrading and refractoring my service endpoints as stateless session beans I fired up JBoss to encounter this error:
org.jboss.deployment.DeploymentException: Cannot create service endpoint; – nested throwable: (org.jboss.ws.WSException: Multiple context root not supported)
I cut-and-paste the error into Google and shortly thereafter I stumbled upon the answer. Apparently, there was quite a major change in functionality between JBossWS 1.2.0 and 1.2.1 which is not documented very well.
Posted: Wed May 16, 2007 07:55 AM Post subject: Re: If I deploy more than one web service I get
——————————————————————————–
Thanks for the valuable discussion. I will try to explain what changes between 1.2.0 and 1.2.1 are causing the problems you encounter.
1.) For EJB3 deployments we need to create a web app for HTTP invocations (obviously)
2.) EJB’s don’t contain web context information, so we derive it automagically.
3.) Until 1.2.0 the context name was derived from the ear/jar name.
4.) This changed with 1.2.1 to an algorithm that derives it from the bean class name
So what’s happening when you deploy a EJB3 jar that contains multiple beans?
The default algorithm derives different context names for each bean in this deployment, which in turn we cannot use to setup the HTTP endpoint and thus throw an exception.This also explains why the following did work:
@WebContext(contextRoot=”/beans”)
Unfortunately this is left out in the specs and thus has been changed many times.
Until we a have a definite solution i suggest you refer to the @WebContext annotation, even though it’s not the most elegant solution.–
Heiko
Finally an answer! Well sort of. I didn’t want to use the annotations. I found an alternative solution in the JBossWS FAQ which described setting the context root explicitly but no information on how to set the context root. Some more searching and I found the DTD for the jboss.xml file which described the XML tags required to set the web service context root. After adding these tags and specifying a context root I successfully deployed my multiple EJB endpoints.
Wow! That’s a lot of work and I haven’t written any of my own business logic yet. Needless to say these issues put me a bit behind schedule on my project. The examples provided in the JBoss J2EE Guide for creating web services are simple enough to follow and are good for getting started but that’s about it. The provided examples work on all of the above mentions versions of JBossWS but fail when you want to get a little more complex with your service. Notice the documentation only provides examples for creating web services that pass primitive types. What about passing custom types? What about passing an array or collection of custom types? None of this is covered and you must refer to outside books and resources to find the answers. In following post I plan to address these topics in detail.
Related posts:
Deon says:
December 7th, 2008 at 11:34 am
I am having a similar problem.
I am using JBoss-ws 2.0.1
I have 2 EJB3 Web services in jar files, but only one will deploy correct at a time.
I am not getting any JBoss Server error. I only know they are not deployed correctly , when I go to the JBossWS page and click on the links and one page will show the wsdl and the other page shows:
404
type Status report
message /ws-cis/AccountSummaryController
description The requested resource (/ws-cis/AccountSummaryController) is not available.
Frank says:
December 7th, 2008 at 12:31 pm
Deon,
In my case I was not even getting two service listings in the jbossws/services page. I fixed that issue by explicitly configuring the context root in the jboss.xml file adding the following xml tags:
You can also use the @WebContext attribute to do the same thing. However, it looks like you may have already done that. Sounds like the wsdl for the second service is not being generated or deployed correctly. I suggest you check the wsdl files in the META-INF directory to make sure they are both being generated.
Also check your webservices.xml file to see that both services are showing up.
Let me know if anything here solves your problem.
Deon says:
December 7th, 2008 at 1:25 pm
Thanks, for the quick reply! I do not have an META-INF directory or a webservices.xml file.
I am using annotations only in a basic eclipse java project.
So maybe that is my problem.
But If this was the problem I would expect neither service to work.
Deon says:
December 7th, 2008 at 1:28 pm
And to add, I am using EJB3 annotations.
Frank says:
December 7th, 2008 at 8:02 pm
Deon, I tried to replicate your problem but could not. I am using JBoss 4.3.0 and JBossWS 2.0.1.GA. I successfully published multiple EJB3 stateless session beans as web service endpoints packaged as a jar file. Here’s what I did… I first create an interface called ServiceOneRemote. This is just a plain interface which defines the business method.
package net.franksalinas.ws; public interface ServiceOneRemote { public String testMethodOne(); }Second I created a class named ServiceOneImpl which implemented the remote interface. Then I applied the all the required annotations which ended up looking like:
package net.franksalinas.ws; import javax.ejb.Remote; import javax.ejb.Stateless; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import org.jboss.annotation.ejb.RemoteBinding; import org.jboss.wsf.spi.annotation.WebContext; @Remote(ServiceOneRemote.class) @RemoteBinding(jndiBinding = "/ejb3/ServiceOneRemote") @Stateless @WebService @WebContext(contextRoot="/myservices") @SOAPBinding(style = SOAPBinding.Style.RPC) public class ServiceOneImpl implements ServiceOneRemote { public String testMethodOne() { return "Hello from ServiceOne"; } }I repeated the above steps for the second service implementation and packaged the classes as a jar file and deployed to my default config on JBoss. After jboss started up I was able to see both service implementations at http://localhost:8080/jbossws/services and both urls displayed the proper WSDL.
Deon says:
December 7th, 2008 at 9:57 pm
Thanks! I did get it to work, but the only way to get it to work was to make the contextRoot different for each service.
@WebContext(contextRoot=”service1″)
@WebContext(contextRoot=”service2″)
This does not make any sense to me. I am not sure why this would work. But it does!
Thanks Again!
Frank says:
December 8th, 2008 at 2:26 pm
That doesn’t make sense to me either. Oh well, glad you got it working!