Sunday, July 10, 2011

EJB 3 example - Exposing a stateless session beans as a web service (JBoss AS6)

In this post, we'll see how to expose an EJB3 stateless session bean as a web service using annotations (= Top-down method given that the starting point is code implementation), within JBoss AS 6. For those who are already familiar with JAX-WS annotations, the implementation part will be straightforward. But the tricky part could reside in how to retrieve its WSDL in order to invoke it : this part depends on the server in use and may even be vendor-specific. If you deploy a web service on a Tomcat server, for instance, it is possible to specify in the server.xml file that you want to publish a list of all the available web services from a given application context...

You'll see below that retrieving the WSDL from a web service deployed on JBoss AS 6 is even simpler.

1° Implementing the web service

One important thing you shouldn't forget is that, as defined in the EJB 3 specifications, only stateless session beans can be exposed as web services. Below, you'll see the 2 ways JAX-WS specifications allow you to follow in order to implement a stateless session bean as a web service : with or without defining an interface.

A. Without defining a service interface

package beans;

import java.math.BigDecimal;

import javax.ejb.Stateless;
import javax.jws.WebService;

@Stateless
@WebService(serviceName = "CalcService", portName = "CalcPort")
public class CalculatorBean {
 
 public Double add(Double operand1, Double operand2){
  BigDecimal op1 = new BigDecimal(operand1.toString());
  BigDecimal op2 = new BigDecimal(operand2.toString());
  
  return op1.add(op2).doubleValue();
 }
}

B With a service interface
package beans;

import java.util.Date;

import javax.jws.WebService;

@WebService
public interface Clock {
 
 public Date getTime();
}


package beans;

import java.util.Date;

import javax.ejb.Stateless;
import javax.jws.WebService;

@Stateless
@WebService(serviceName="G-Shock", portName="G-Shock-Port", endpointInterface="beans.Clock")
public class ClockBean implements Clock{

 @Override
 public Date getTime() {
  return new Date();
 }

}
 

To test these classes, simply create an EJB project with Eclipse (FYI, I'm using Eclipse Helios). Create a source folder named "src" within this project. Then create a package named "beans". Paste the 2 classes and the interface in the "beans package" and deploy the whole project on the JBoss AS server.

2° Accessing the published WSDL

Once both the services are deployed, go to the administration page of your JBoss AS server (since I'm working locally using the 8080 port, mine is located at http://localhost:8080) :


Then, click on "JBoss Web Services Console". This link will bring you into the JBossWS page. Then, click on  "View a list of deployed services" This will bring you to a page where you'll see a list of available web services : 


From this page, you can click on the "Endpoint Address" of each service, which will bring you to the corresponding WSDL.

VoilĂ , you're go to go with your first EJB 3 compliant web service.