Turn EJB components into Web services

Build and deploy an EJB component as a Web service with JAX-RPC

The evolution of Web-related technologies has changed the way applications in an organization communicate with customer and partner applications. Like every popular technology, Web services came like a wave and have assimilated deeply into IT organizations. Having revolutionized the IT world, Web services are here to stay. Thus, to compete in the market space, certain parts of your enterprise applications must be exposed as Web services.

The wide acceptance of Web services by companies has changed the way applications are designed, and Java developers must adapt to a service-oriented architecture. If you develop applications using J2EE, you are probably in the best position to adapt to a service-oriented architecture and expose your application as a Web service. Most J2EE application servers, such as Oracle Application Server 10g and BEA WebLogic, provide support for building and deploying Web services applications. However, J2EE 1.4 standardized building and deploying Web services applications with Java API for XML-based Remote Procedure Call (JAX-RPC).

JAX-RPC enables developers to write Web services applications by using Java classes and EJB (Enterprise JavaBeans) components. Numerous business applications have been written to EJB to encapsulate business logic in the middle tier. If you use EJB in your enterprise applications, you can easily expose them as Web services without redeveloping the business logic. This article discusses how you can build and deploy an EJB component as a Web service by using JAX-RPC and provides some guidelines for using EJB components as Web services.

What is JAX-RPC?

Before we dive into the details of developing an EJB Web service, let's quickly examine JAX-RPC. JAX-RPC, defined under Java Specification Request 101 in the Java Community Process, provides the Java API for building and accessing Web services. It can be seen as the heart and soul of building and deploying Web services with J2EE. JAX-RPC provides a simple, robust platform for building Web services applications by hiding from the application developer the complexity of mapping between XML types and Java types and the lower-level details of handling XML and SOAP (Simple Object Access Protocol) messages. It introduces a method call paradigm by providing two programming models: a server-side model, for developing Web services endpoints using Java classes or stateless EJB components, and a client-side model, for building Java clients that access Web services as local objects. JAX-RPC 1.1 mandates use of SOAP 1.1 and interoperability with other Web services built with other technologies such as Microsoft .Net. Several J2EE 1.4-compliant application servers, such as Oracle Application Server Containers for J2EE (OC4J) 10.0.3, Sun ONE (Open Network Environment) Application Server, and IBM Websphere V6, support JAX-RPC.

Developing and deploying an EJB Web service

EJB components, by design, are meant for distributed computing and are hence well suited for exposure as Web services. EJB supports declarative transactions and security, and these benefits can also be leveraged if you decide to use EJB components as Web services. J2EE 1.4 allows exposing only stateless session beans as Web services with JAX-RPC.

By their nature, SOAP and Web services are stateless, and hence stateless session beans are an ideal choice for exposing as Web services. Stateless session beans are used for business operations such as checking someone's credit, charging a bank account, or placing an order, and these operations are a perfect fit for exposure as Web services. You can use a stateless session Web service to accomplish any of these business operations by accessing a persistence layer such as CMP (container-managed persistence) entity beans or an O/R (object/relational) framework such as TopLink, or sending a message to a JMS (Java Message Service) queue that activates an MDB (message-driven bean) to process the business rule.

Guidelines for development

If you use a Session Fa�ade design pattern in your J2EE applications, it will prove easier for you to expose your business process as a Web service. However, exposing all session beans in your application as Web services is not a good idea and will pose a management nightmare. A session bean that implements a business activity and will be used by another remote application is an ideal candidate for exposure as a Web service. The session fa�ade must be coarse-grained, not fine-grained. For example, an ideal choice for an EJB Web service is an EJB component that has methods for completing an order or charging a credit card, not an EJB component that just provides access to an entity bean's getter and setter methods. You must remember that Web services are invoked with SOAP, that you should avoid exposing an EJB component as a Web service if it may involve a long-running business transaction, and that you should also avoid calling that bean from a Web application.

Developing an EJB Web service

If you already have a stateless session bean, you can easily expose it as a Web service. You must perform the following tasks to expose your EJB component as a Web service:

  • Create a Web service endpoint for the stateless EJB component. Change the EJB deployment descriptor, ejb-jar.xml, to define the endpoint.
  • Create a Web services definition, using the WSDL (Web Services Description Language) and Web services deployment descriptors such as webservices.xml.
  • Package your EJB component in an ejb-jar with the descriptors and WSDL, and deploy it into your application server of choice.

Let's take a simple stateless session bean example, TimeServiceBean, and walk through each of these steps. You can download a fully functional example of the EJB Web service this article discusses from the Oracle Technology Network.

Your EJB component's Web service endpoint should implement the java.rmi.Remote interface, and every method exposed in the endpoint interface must throw java.rmi.RemoteException. The following code is the Web service endpoint for an EJB component called TimeService:

package time; 
import java.rmi.RemoteException;
import java.rmi.Remote; 
public interface TimeService extends Remote
{
public String getDateTime (String name) throws RemoteException;

If you just want your EJB component exposed as a Web service, you do not need to build other interfaces. But you can use the same component directly from a J2EE application or as a Web service, and the J2EE container will use the same bean pool for both uses.

The TimeService Web service interface exposes a getDateTime() method, accepts java.lang.String as a parameter, and returns java.lang.String as a return type. You can use only primitives and classes that are JAX-RPC value types as parameters or return types for the EJB methods defined in the Web service endpoint interface. Some examples of JAX-RPC value types are nonprimitives such as java.lang.String or java.lang.Double and Java mappings of Mime (Multipurpose Internet Mail Extensions) types such as java.awt.Image or javax.xml.transform.Source. User-specific Java types may also be used if the user provides a serializer for those types. Most vendors provide a custom serialization registration framework.

For exposing the Web service endpoint interface, an entry is required in ejb-jar.xml. For example, we have the following entry for our TimeService Web service:

<session>
<display-name>TimeServiceEJB</display-name>
<ejb-name>TimeServiceEJB</ejb-name>
<service-endpoint>time.TimeService</service-endpoint> 
<ejb-class>time.TimeServiceBean</ejb-class>
<session-type>Stateless</session-type>
...
</session>

The most important things for the Web service are the WSDL and the Web services deployment descriptor webservices.xml file. The WSDL describes the Web service and is the contract to which the Web service guarantees it will conform.

Following is the WSDL for the TimeService Web service:

<?xml version="1.0" encoding="UTF-8"?> 
<definitions name="MyTimeService" targetNamespace="urn:oracle-ws" xmlns:tns="urn:oracle-ws" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<types/>
<message name="TimeService_getDateTime">
<part name="String_1" type="xsd:string"/></message>
<message name="TimeService_getDateTimeResponse">
<part name="result" type="xsd:string"/></message>
<portType name="TimeService">
<operation name="getDateTime" parameterOrder="String_1">
<input message="tns:TimeService_getDateTime"/>
<output message="tns:TimeService_getDateTimeResponse"/></operation></portType>
<binding name="TimeServiceBinding" type="tns:TimeService">
<operation name="getDateTime">
<input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="urn:oracle-ws"/></input>
<output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="urn:oracle-ws"/></output>
<soap:operation soapAction=""/></operation>
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/></binding>
<service name="MyTimeService">
<port name="TimeServicePort" binding="tns:TimeServiceBinding"><soap:address location="REPLACE_WITH_ACTUAL_URL"/></port> 
</service>
</definitions>

If you look carefully, you will find that the WSDL has a complete description of the TimeService EJB Web service, including the port, operations, and message types. There is no difference in the WSDL between an EJB Web service and another Web service.

As we discussed earlier, deployment of an EJB Web service in J2EE requires a standard compliant deployment descriptor named webservices.xml (shown below) in META-INF in the ejb-jar file. This descriptor specifies the set of Web service descriptions for deployment into the J2EE application server and their dependencies on container resources and services:

<description>A Web service to serve current Time</description> 
<webservice-description>
<webservice-description-name>TimeServiceEJB</webservice-description-name>
<wsdl-file>META-INF/MyTimeService.wsdl</wsdl-file>
<jaxrpc-mapping-file>META-INF/mapping.xml</jaxrpc-mapping-file>
<port-component>
<description>port component description</description>
<port-component-name>TimeServicePort</port-component-name>
<wsdl-port xmlns:ns="urn:oracle-ws">ns:TimeServicePort</wsdl-port> 
<service-endpoint-interface>time.TimeService</service-endpoint-interface>
<service-impl-bean>
<ejb-link>TimeServiceEJB</ejb-link>
</service-impl-bean>
</port-component> 
</webservice-description>

If you look at the webservices.xml file, you will see that it specifies the location of the WSDL; mapping.xml, which contains Java-to-WSDL mapping; and the service endpoint interface for the TimeService EJB component.

Several implementation-specific references such as the context root and endpoint addresses cannot be specified in the Web services deployment descriptor and must be specified in the vendor-specific deployment descriptor, because most of these references are specific to a particular J2EE server vendor. For example, if you use OC4J, you will need to package an oracle-webservices.xml file in the ejb-jar to define these properties. For our TimeService EJB component, the contents of the oracle-webservices.xml are as follows:

<oracle-webservices>
<context-root>/ejbws</context-root>
<webservice-description name="TimeServiceEJB">
<port-component name="TimeServicePort">
<endpoint-address-uri>/timeport</endpoint-address-uri>
</port-component>
</webservice-description>
</oracle-webservices>

The context-port and endpoint-address-uri imply that the Web service's endpoint can be reached via http://<hostname>:<port>/ejbws/timeport.

A tool provided with the application server usually generates WSDL, webservices.xml, and vendor-specific deployment descriptors such as oracle-webservices.xml. For example, if you use the J2EE Reference Implementation, you can use the wscompile tool to generate the WSDL and the Web services deployment descriptors. However, you can use an IDE that makes Web services development much easier and your development cycle much faster. You can avoid several mundane tasks such as creating the endpoint interface, the WSDL, and the deployment descriptors and instead focus on creating business logic. IDEs provide wizards for creating the Web service endpoints and for generating the WSDL and the deployment descriptors.

The J2EE 1.4 Blueprint application Java Adventure Builder 1.0.1 provides a nice design pattern and guideline for building a Web services application using J2EE and can be used as a reference application.

Invoke a Web service

An EJB Web service does not differ from any other Web service and can be invoked by a client written in Java, .Net, or any other programming language. A detailed discussion of Web service clients reaches beyond this article's scope, but let's examine how a Web service can be invoked from either a standalone Java program or a J2EE application module such as a servlet or an EJB component.

1 2 Page
Recommended
Join the discussion
Be the first to comment on this article. Our Commenting Policies
See more