Three specifications tightly integrate JAX-RPC with J2EE:
J2EE 1.4 specifications (JSR-151)
EJB 2.1 specifications (JSR-153)
Web services for J2EE (JSR-109)
J2EE 1.4 includes JAX-RPC as a required API, which means that all J2EE 1.4 application servers will support JAX-RPC. The EJB 2.1 specifications-part of J2EE 1.4-also define how an EJB can be exposed as a Web service and how EJBs can consume a Web service. The Implementing Enterprise Web Services specification will lay out the deployment and service requirements for portability of client and server code across containers.
EJB 2.1 allows a stateless session bean to be exposed as a Web service, by defining a new interface type in addition to the home, local, and remote interfaces. It is called an endpoint interface and is essentially the JAX-RPC service definition. EJB developers provide the service definition and the EJB class. As Figure 10.13 shows, the container generates the implementation of the endpoint interface. much as it generates the implementation of the EJBObject during deployment.
The container exposes the EJB through its service endpoint interface and a WSDL document that clients can use. Once it is deployed, clients use it like any other JAX-RPC service-that is, they access this stateless session bean using the JAX-RPC client APIs over an HTTP transport, just like clients covered earlier in the chapter.
EJBs can look up other Web services with Java Naming and Directory Interface (JNDI), using a logical name called a service reference. It maps to a service-ref element in the deployment descriptor, obtains a stub instance for a Web service endpoint, and invokes a method on that endpoint. The J2EE client or EJB can do this, as Figure 10.14 and Listing 10.18 show.
InitialContext ctx = new InitialContext(); BillPayService service = (BillPayService)ctx.lookup ("java:comp/env/service/billpayservice"); BillPay stub=(BillPay)(serviceproxy.getBillPayPort()); PaymentConfirmation conf= stub.schedulePayment(new Date(), "my account at sprint",190); <enterprise-beans> <session> <service-endpoint> com.flutebank.billpayservice.BillPay</service-endpoint> <ejb-class> com.flutebank.billpayservice.BillPayEJB </ejb-class> <service-ref> <service-ref-name> service/billpayservice</service-ref-name> <service-ref-type>com.flutebank.BillPayImpl</service-ref-type> </service-ref> </session> </enterprise-beans>
Implementing a JAX-RPC service as an EJB in a J2EE container has four significant advantages:
Integrated support for transactions
A comprehensive security model
Integration with existing business logic
Scalability through the application server (e.g., clustering and failover)
If the service was implemented as a class and not deployed in a J2EE container, it forgoes the advantage of the ACID (atomic, consistent, isolated, and durable) characteristics of the Java Transaction API (JTA) transaction. A non-EJB class in a J2EE container could still leverage a JTA transaction by directly using the javax.transaction.UserTransaction object though a JNDI lookup. The stateless EJB with its service endpoint interface, like other EJBs, can propagate and demarcate transactions in a J2EE container and also use bean-managed transactions. It can also leverage the role-based security features the J2EE container provides. (Note, however, that transaction context propagation is not required by the current JAX-RPC specifications.)
Using just a servlet endpoint and a Java class(s) (without an EJB) implementation has the following advantages:
Generally better performance
Simplicity in deployment
No need for a full-blown J2EE application server; any Servlet 2.3-compliant Web server or container can be used
Implementing Enterprise Web Services (JSR-109) defines a complete mechanism for deploying Web services in a container, using a webservices.xml file for a module and a webservicesclient.xml file for the clients. The key elements of the former are shown below.
<webservices> <description>A sample file </description> <webservice-description> <wsdl-file>billpayservice.wsdl</wsdl-file> <port-component> <port-component-name>BillPayerComponent</port-component-name> <port-qname-namespace>http://www.flutebank.com/xml</port-qname-namespace> <port-qname-localname>BillPayService</port-qname-localname> <service-def-interface>com.flutebank.billpayservice.BillPayt </service-def-interface> <service-impl-bean> <!--If the service implementation is an EJB → <ejb-link >com.flutebank.billpayservice.BillPayEJB </ejb-link> <!--If the service implementation is a Servlet → <servlet-link>com.sun.xml.rpc.server.http.JAXRPCServlet</servlet-link> </service-impl-bean> </port-component> </webservice-description> </webservices>
At the time of writing, all three of these specifications were still in draft form. They may possibly undergo changes as a part of the Java community process.