JAX-RPC

JAX-RPC is a specification that is developing through the Java Community Process (JCP). It aims to provide a JCP-sanctioned standard set of Java APIs for both a client-side and server-side programming model.

These APIs leverage interoperable communications within Java applications with a protocol design center based on, but not limited to, SOAP. It covers the following areas:

  • A Java code generation model for client-side stubs and server-side tie classes, based on a set of conventions for mapping WSDL to Java and Java to WSDL.

  • An API for dynamic SOAP-RPC and a Call interface that is conceptually similar to Apache SOAP. Call semantics include synchronous invoke and synchronous invoke/one-way. JAX-RPC does not address asynchronous invocation in its 1.0 rendition. A true asynchronous model would require callbacks (onMessage, etc). The one-way invocation model defined in the API is considered synchronous.

  • A model for defining a service, registering it, and invoking it within the J2EE and J2SE environments. This model covers typical J2EE/J2SE deployment issues such as creating deployment descriptors and packaging Web Application Archive (WAR) files.

  • A binding to SOAP, including SOAP Fault handling through Java exceptions and HeaderFault processing.

  • Type mappings between Java and XML datatypes.

  • A service-side invocation handler mechanism used to chain together service method invocations.

  • A reference implementation (RI) that provides a runtime implementation and a code generation tool, xrpcc.

  • A serialization framework for marshalling and unmarshalling data between Java and XML based on soap-encoding rules. The RI from Sun includes an implementation of this framework.

JAX-RPC is a funny kind of animal. Finding the right kinds of things to write about it in the context of this book was a challenge. At the time of writing, the specification was still evolving. This chapter is based on a Version 0.6 snapshot of the specification’s first public draft, issued as part of the Winter 01 Java Web Services Developer Pack. There are no known implementations, except for the RI (which is evolving with the specification) and the Apache Axis project (which is in alpha stage and based on Version 0.5 of the specification). Therefore, many examples in this section are repurposed directly from the specification. Several areas in the specification are in flux, need more definition, and are extremely likely to change before it hits a 1.0 status. Currently, the specification is 152 pages long and has enough information in it to comprise a whole book when it’s finally finished.

In spite of its al dente status, the JAX-RPC specification has a brief working tutorial (as do all JAX products) that walks you through installation and setup and guides you through building a simple “Hello World” example. The RI runtime requires Tomcat; its installation, code generation tool, and deployment tool are based on Ant.

Most of the specification iterates over details and rules for mapping things between Java, XML, SOAP, and WSDL—not only for infrastructure provider runtime interactions, but also to provide directives and guidelines for code generation tools. If you are building a code generation tool, you will need more than we are presenting in this book.

Considering these factors, we still chose to write about JAX-RPC because it is a significant piece of functionality that is slated for J2EE 1.4. Therefore, its “baketime” will have to be short. We’ll focus on the things that are baked and concentrate on the things that are exposed to the application developer. As the specification progresses, we will update our examples and provide new examples to go with them. Check this book’s home page on the O’Reilly web site (http://www.oreilly.com/catalog/javawebserv) occasionally to see what we have placed there.

Stubs and Tie Classes

The concepts of "stub” and “tie” are not unique to JAX-RPC. The terms have been used in many other distributed-computing technologies, such as RMI, CORBA, and DCE RPC. Some of you may also be familiar with the terminology “stubs and skeletons.” To understand stubs and ties, it is important to understand what’s so exciting about remote procedure calls in the first place. The idea behind a remote procedure call is that an application makes a call to a method on an object, and the actual implementation of that object exists in another process space. The processes are typically located on different machines separated by a network connection. The application making the method call (the client) does not need to know that it actually makes a call to a remote object (the service), nor does it need to worry about the details of how that happens.

The client application has a local object, the “stub,” that acts as a proxy for the remote object. The stub object has the same methods as the remote object, but does not implement the business logic. Instead, the stub represents an interface to an underlying infrastructure that is responsible for packaging the method name and its parameters into an agreed-upon wire format. This operation is sometimes referred to as marshalling or encoding. Upon reaching its destination, the skeleton or tie class is responsible for unmarshalling the wire format and reconstructing the data into a form that is recognizable by the server application. In the case of a remote procedure call, this means invoking the actual method with the expected parameters and datatypes, then marshalling return values back to the sender.

An assumption here is that a tool generates the stub and tie code, isolating the developer from the details of the marshalling and the transport protocol. In other distributed-computing technologies, in which both sides of the conversation are under the domain of a single vendor, a tool typically generates the stub and the skeleton at the same time, based on a generic description of an interface. With SOAP and web services, we break tradition because we can’t assume that the invoking client and the receiving service are part of the same software infrastructure. It is likely that each end of the conversation is built upon different software platforms. The one constant in the picture is that each side needs to interact with the same interface definition defined in WSDL and speak the same interoperable protocol, such as SOAP, which is also specified in WSDL as a binding.

Stub generation by a tool is only one option in JAX-RPC. We will discuss other options in Section 7.4.

WSDL to Java, Java to WSDL

JAX-RPC defines a mapping of datatypes between WSDL and Java. The mappings cover simple datatypes, such as short, int, long, float, and double. It also has some fairly dry and boring rules about the mapping of arrays, structs and complex types, and enumerations. The good news is that this part of the specification is intended for vendors who build code generation tools that hide all these details behind a stub class.

You should also be familiar with definitions of parameter-passing modes. Some highlights that we will cover include remote references, pass-by-copy, and Holder classes.

Remote references

The generally accepted definition of a remote reference is an instance of a proxy that represents a particular instance of a remote object or service that can be transferred from one client to another. Remember that JAX-RPC doesn’t support remote references in its pre-1.0 rendition, largely because SOAP doesn’t have a model for remote references, either. A JAX-RPC client or server must be able to support any arbitrary SOAP message to or from a non-JAX-RPC entity.

Pass-by-copy and Holder classes

In a WSDL operation, a message part can be specified to appear within the input message only. This message part is considered an In parameter. A WSDL message part appearing only within an operation’s output message can be thought of as an out parameter. Message parts appearing in both input and output messages within a WSDL operation can be called inout parameters.

A parameter marked as in indicates that the sending client has no further concern with what that remote procedure does with it once it is sent over the wire. This concept is commonly referred to as pass-by-value or pass-by-copy. An out parameter is a return value. An inout parameter is expected to be modified by the remote procedure, causing the calling client to see the modified value after the method invocation returns.

Generally speaking, you can support inout parameters in two ways: with pass-by-reference and Holder classes. In distributed-computing environments that support pass-by-reference, an object reference is a specific datatype that can be passed as a parameter to a remote object. It can be treated as the handle to an actual instance of the parameter. Once the remote method call is complete, it may be dereferenced by the client program to obtain the newly modified value. The underlying infrastructure marshalls the data over the wire to get the right result.

Java doesn’t support pass-by-reference natively for primitive types. Instead, JAX-RPC uses Holder classes, which are classes used by the underlying infrastructure to act as a place to hold the values. A stub uses a Holder to store the modified values after the method invocation so the calling client can then access them. Here’s an example illustrating the use of Holders:

public interface StockQuoteProvider extends java.rmi.Remote {
// Method returns last trade price
float getStockQuote(String tickerSymbol,
    javax.xml.rpc.holders.IntHolder volume,
    javax.xml.rpc.holders.FloatHolder bid,
    javax.xml.rpc.holders.FloatHolder ask)
  throws java.rmi.RemoteException;
}

//Java
package javax.xml.rpc.holders;
public final class IntHolder {
    public int value;
    public IntHolder(  ) { }
    public IntHolder(int value) {
    this.value = value;
    }
}

Holders are also used to represent complex data structures as parameters. The java.xml.rpc Holders package defines Holders for all the built-in Java primitives. Beyond that, the code generation tool is responsible for creating Holders for the parameters. In either case—whether using the supplied Holder classes or the custom generated ones—-the code generation tool is also responsible for creating the code that serializes and deserializes data sent across the wire.

Generated service interface

JAX-RPC allows a code generation tool to create an implementation class for the Service interface based on an existing WSDL document. While the implementation details of the generated class are vendor-specific, the generated interface is required to adhere to the following design pattern:

public interface <ServiceName> extends javax.xml.rpc.Service {
    public <ServiceDefInterface> get<Name of the wsdl:port>(  )
        throws JAXRPCException;
    ...
}

In the previous listing, the <ServiceName> of the generated service interface is mapped from the name attribute of the corresponding wsdl:service definition. The <ServiceDefInterface> name is mapped from the portType, and the get <Name of the wsdl:port> ( ) method is mapped from the—you guessed it—wsdl:port definition’s name attribute. For example, given the following WSDL definition:

<service name="StockQuoteService">
    <port name="StockQuoteProviderPort" binding="tns:somebinding">
        <http:address location="http://example.com/"/>
    </port>
</service>

<portType name="StockQuoteProvider">
    <operation name="GetLastTradePrice"
        parameterOrder="tickerSymbol">
    ...
    </operation>
</portType>

a JAX-RPC implementation creates the following Java interface; the get method returns an instance of a stub class that implements the <ServiceDefInterface>:

package com.example;
    public interface StockQuoteService extends javax.xml.rpc.Service {
    public StockQuoteProvider getStockQuoteProviderPort(  )
        throws JAXRPCException;
    ...
}

Value types

Value types are specific to the generation of WSDL from a Java class. A value type is a special form of serializable class, containing data values that are capable of being marshaled between a client and a service. It must implement Serializable, but does not follow the standard rules for Java serialization. Only public, nontransient data members are mapped to the WSDL. A value type may also be a JavaBean, in which case, the WSDL generation may use bean introspection to identify the properties and map them to the WSDL. The methods in the value class are not mapped to the WSDL; it is strictly for data. Whether a value type should use the Serializable marker interface or whether a different interface should be defined is still undecided.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset