As Published In

Oracle Magazine
January/February 2004
Developer WEB SERVICES

Creating Web Services with J2EE 1.4

By Mike Lehmann

JAX-RPC standardizes Web-services implementation.

Before the introduction of the Java application-programming interface (API) for XML Remote Procedure Call (JAX-RPC), released as part of J2EE 1.4, developers had no standardized way to implement and consume Web services in Java that was common across products by different vendors. That meant developers could not use a common skill set across J2EE vendor platforms to build Web services.

With JAX-RPC, developers have a common API for developing Web services on the Java platform. Oracle is one of the first vendors to put out an early implementation of J2EE 1.4 with JAX-RPC, both on the server, with the Oracle Application Server 10g Containers for J2EE (OC4J), and in a design time, with a JAX-RPC extension for Oracle JDeveloper 10g.

Let's go through the steps of using the JAX-RPC API, including creating a simple Java interface, implementing a Java class based on that interface, deploying to a J2EE 1.4 container, and, finally, building a JAX-RPC client.

Building the JAX-RPC Interface and Implementation

A Web service is invoked when a SOAP message is sent to a Web-service endpoint—the location where the server will parse and transform it into a Java call to an underlying component. JAX-RPC provides a programming road map for developers who want to build this endpoint. The first two steps necessary for JAX-RPC developers to build that endpoint will be familiar to any Java developer—develop a Java interface defining a public set of methods that clients will invoke and then a Java class implementing those interfaces.

For example, using the famous Oracle schema SCOTT and the equally well-known table EMP as business data, you could construct many Web services that return useful information. Let's build a service that has one method taking an employee number as a parameter and returning the employee's salary:

1  import java.rmi.*;
2  public interface EmpInterface extends java.rmi.Remote
3  {
4    public String getEmpSalary(Integer empNo) throws java.rmi.RemoteException;
5  }

Notice two things about this interface: First, it extends the class java.rmi.Remote. Second, each method throws the exception java.rmi.RemoteException.

If you have ever implemented servlets or Enterprise JavaBeans before, you know that these two classes are the traditional server-side classes J2EE developers work with for remote components. Because Web-service endpoints are just another remote object, the JAX-RPC designers decided to utilize these same classes. Their usage gives existing J2EE developers a natural on-ramp to JAX-RPC, leveraging their knowledge while taking advantage of a proven programming model.

Next, let's implement the interface so your Web service does something of interest—in this case, querying the EMP table, given an employee number for salary. Listing 1 shows part of the class focusing on the method implementations and some areas of interest specific to JAX-RPC.

The primary concept to notice in this code, beyond the simple JDBC details of the business method getEmpSalary, is the methods init and destroy from the ServiceLifeCycle interface. These two methods give a useful handle to developers to implement startup or shutdown logic in a standardized way—for example, implementing a JDBC connection cleanup sequence of code in the destroy method.

Publishing a JAX-RPC Web Service

Now that you've created the Web-service interface, you're ready to publish your JAX-RPC Web service. To publish the Web service—that is, package it and deploy it so external clients can send and receive SOAP messages to it—do the following:

  1. Create the artifacts necessary for the server to understand that this set of Java classes is a Web service. Conceptually, you are creating a binding between the inbound SOAP message to an invocation and returned results of a particular Java class and method.
  2. Create a Web Service Description Language (WSDL) document describing the service. The WSDL document becomes the external contract to which the Web service guarantees it will conform. Most tools, regardless of programming language, are able to generate a Web-services client based on this WSDL.
  3. Create the deployment packaging so the JAX-RPC service can be deployed to a J2EE server. This step, often generically referred to as Java Specification Request (JSR) 109, describes the required artifacts every J2EE server needs for a successful deployment and execution of a JAX-RPC Web service.

To carry out these steps, you can use the newly released JAX-RPC design time for Oracle JDeveloper 10g. A command-line analog for this, the Web Services Assembler, is part of the OC4J. (These tools can be downloaded from OTN; see the Next Steps box.) Using the JDeveloper wizard, these steps are as simple as identifying the class you want to publish, selecting the methods you wish to expose as Web services, and defining the style of SOAP messaging (RPC/ Encoded, RPC/Literal, Document Literal).

In prior releases, Oracle provided an implementation of Web services strictly conforming to the canonical Web-services standards SOAP, WSDL, and UDDI for interoperability, but, like all J2EE vendors' implementations at the time, Oracle's was an application-server-specific implementation. As a result, the mechanical steps in the old style tend to be very similar for JAX-RPC. Now, however, JAX-RPC standardizes the configuration across J2EE vendors, giving not only interoperability at the Web-services level but also portability at the implementation level.

The resulting file structure requires five additional files beyond the implementation and interface classes; in our case, generated by a JDeveloper wizard. First, there are two files familiar to Web services developers—a WSDL file, EmpService .wsdl, describing the Web-service interface and parameters in XML, and the web.xml file, which does the basic configuration of the Web service as a servlet.
Next Steps

DOWNLOAD Oracle Containers for J2EE
otn.oracle.com/tech/java/oc4j/1013

TEST JAX-RPC in a design time using Oracle JDeveloper JAX-RPC extension
otn.oracle.com/products/jdev

The files get more interesting with the EmpService-java-wsdl-mapping.xml file. For each Java method and its parameters defined in the interface Emp.java, this file provides a mapping to the corresponding WSDL portType (equivalent to the Java interface), WSDL operations (corresponding to the Java methods), and WSDL XML messages (comparable to the method Java-typed parameters).

The last two files of interest are webservices.xml and oracle-webservices .xml. The first describes the JAX-RPC mapping file's location and the Web-service endpoint. The second is specific to Oracle's JAX-RPC implementation and provides additional binding information to Oracle's J2EE container. After these configuration files are packaged together with the Emp.java and EmpImpl.java implementation files into an Enterprise Archive (ear) file, they can be deployed to the Oracle Application Server as a J2EE application and invoked as a Web service.

Building a Client

Just as JAX-RPC standardizes the server side of J2EE Web services, it provides a set of standard models for building JAX-RPC clients. Let's look at a classic static stub-client example from J2SE, in which a local client acts as a proxy for the remote service. JAX-RPC supports other client styles, including dynamic proxy, dynamic interface invocation, and J2EE clients.

The goal of any Web-services client is to programmatically construct a SOAP message conforming to the specification laid out in the Web-services WSDL file. To that end, JAX-RPC implementations typically provide a WSDL-to-Java client generation tool, like those found in both Oracle Application Server and Oracle JDeveloper.

Listing 2 illustrates a sample JAX-RPC client. The Java class doing all the heavy lifting is EmpService_Impl.java, which represents a remote instance of the Web service defined by the WSDL. Generated along with it is a set of classes representing the datatypes sent and received by the Web service in the Java package types. Line 9 is where the work happens. Here, the logical WSDL port is returned by the service proxy EmpService_Impl.java and cast to the same Java interface, EmpInterface.java, used to implement the service in EmpImpl.java. Once this cast is done, the actual work invoking the Web service is accomplished in line 10, where the getEmpSalary method on the remote Web service is invoked and the data is returned to the variable response.

Mike Lehmann ( mike.lehmann@oracle.com) is a principal product manager for Oracle Application Server Containers for J2EE.

E-mail this page
Printer View Printer View
Oracle Is The Information Company About Oracle | Oracle RSS Feeds | Careers | Contact Us | Site Maps | Legal Notices | Terms of Use | Privacy