Understanding Remote Object Access


All calls invoked on objects residing on a JVM located on a network somewhere in the digital world are remote calls. A Remote Procedure Call represents a procedural invocation from a process on a client machine to a process on a remote machine. RMI-IIOP facilitates distributed object interaction between the two processes across platforms and operating systems. In essence, RMI-IIOP is protocol and platform agnostic. Clarifying this concept one step further, RMI-IIOP allows developers to invoke methods on objects rather than calls on remote procedures.

The benefit of using RMI-IIOP is that it conforms to object-oriented programming concepts, including encapsulation, implementation inheritance, and programming to interfaces, rather than using traditional inheritance. Also, the Remote Method Invocation results in the specified object executing in a separate JVM, which enhances performance. As previously stated throughout this text, the J2EE specification defines what developers and vendors should adhere to but never how they should do it. In this way, RMI-IIOP fits nicely into the scheme.

The following is a list of items that must be considered when invoking remote calls on objects:

  • Marshaling and unmarshaling When a client calls a remote object, the machine’s memory layout is unknown. RMIs and RPCs facilitate passing parameters over the network. Another issue arises when an object reference is sent. In any case, the challenge to developers is that the pointer being sent is not valid on the remote machine because its memory layout is completely different from that of the client machine. The marshaling and unmarshaling process allows developers to manipulate parameters so they are usable on the remote machine.

  • Passing parameters by value and by reference When values are passed by value, a copy of the data, rather than the original value, is passed. By using this method, any data changes are reflected in the copy rather than in the original. Conversely, a value passed by reference reflects data changes directly in the object. It is important to have flexibility when passing parameters. RMI-IIOP supports both methods.

  • Surviving system failure Imagine if a distributed application has numerous JVMs collaborating to provide a business solution for a single client. If one machine crashes, the distributed application must survive the system failure. RMI-IIOP provides a standardized methodology for handling such disastrous events.

    Note

    J2EE 1.3-compliant servers are mandated to provide RMI-IIOP implementations that enable developers to perform successful networking operations. This represents one piece of the J2EE server’s many components and thus fulfills the promise of J2EE, which assures application portability.

Investigating the Interfaces

The remote interface exposes specified information about an object, such as the method names and their parameters. The interface hides the implementation from the client.

Note

The implementation represents business logic, algorithms, and data. Separating the interface from the implementation allows for varying program logic without altering client code. This conforms to the object-oriented principle of allowing object substitutability, a chief benefit provided by programming to interfaces.

RMI-IIOP makes extensive use of this principle. What does this mean to developers? You cannot invoke a remote method directly on an object. The RMI-IIOP invocation must be performed on the remote interface to the object’s class. Therefore, you must create a remote interface that extends the interface; this is called java.rmi.Remote. In addition, the custom interface must have within it a copy of each method exposed by the remote interface.

Here is a typical sequence of events for accessing a remote object:

  1. The client call invokes a specified business method on a remote component interface. Recall that a client is not allowed to invoke a method on an object directly; it must be invoked on the implementation interface.

  2. The client passes an object as a parameter. This can be done by passing the parameters either by value or by reference.

  3. The remote interface stub marshals the parameter before passing it to the EJBObject. This object functions as a proxy for the container. The client thinks it is interacting with a local object.

  4. The EJBObject skeleton must then take the object parameters and unmarshal them.

  5. The container performs the required security, transaction, and life cycle services before the object is passed on to the corresponding business method(s) contained in the remote interface. It is now executed on the bean instance.

  6. The business method result is returned to the EJBObject.

  7. The EJBObject marshals the result and transmits it back to the remote component interface.

  8. Finally, the remote component interface unmarshals the object and presents the result to the client.

    Note

    With EJB 2.0, when a client bean instance invokes business methods on an entity bean located within the same JVM, the client can use the local interface rather than invoking the services of a remote object.

In the following example, a remote object exposes one method: compute(). It generates a random number each time it is called. The object is an entity bean.

import java.rmi.Remote;
import java.rmi.RemoteException;
/**
*This remote interface represents the remote object
*Clients use this interface to execute operations on the remote object.
*/
public interface IFCEObjecGen extends Remote {
public long compute() throws RemoteException;
}

In order to make an object a remote object and provide access for a client, it is necessary to execute one of the following steps:

  • Extend class javax.rmi.PortableRemoteObject. This is a base class from which a remote object can be derived. When the client invokes a call on the remote object and the object instance is created, it calls the RemotePortable remote object’s constructor. This sequence makes the object available to be called remotely.

  • Manually export the object so it is available for invocation by remote hosts as follows: call javax.rmi.PortableRemoteObject.exportObject(). Note that the Java language does not permit multiple implementation inheritance; therefore, it is not possible to extend PortableRemoteObject.

Here is the remote object class:

import java.rmi.RemoteException;
import javax.rmi.PortableRemoteObject;

public class RndNumGen()
extends PortableRemoteObject
implements IFCEObjecGen
/*
*The remote object's constructor
*/
public RndNumGen() throws Exception, RemoteException {
super();
}

/*
* Generate a unique random number
*/
public synchronized long compute() throws RemoteException {
return i++;
}
private static long i = System.currentTimeMillis();

}

In the remote object constructor, the superclass provides access to remote clients. It makes the object available at a random port number. Once the remote object’s constructor is called, the object is always available to anyone.

Note

RMI-IIOP permits multiple clients to connect to a server at once. Because the remote object implementation may possibly have many threads running at once, you should place a synchronized block around the compute() method to ensure that only one client can generate a unique random number at a time.

Object Serialization

When a client uses RMI-IIOP to invoke a method, all parameters are passed by value. This means all parameters are copied from the client machine to the remote machine. Passing by value presents a problem. When an object is passed over the wire and the object contains references to other objects, how are those external references resolved? Fortunately, the process of serialization resolves this issue. Java converts the object into a bit-blob representation of the object. It is possible to send bit-blobs wherever desired over the wire. The Java language takes care of all serialization processing. RMI-IIOP uses object serialization to send bit-blobs over the wire. To inform Java that your object is serializable, you implement the java.lang.Serializable interface.

Note

The java.lang.Serializable interface defines no methods whatsoever. It therefore serves as a marker interface.

Developers can create a custom serialization by implementing the writeobject() method. It is also possible to provide custom serialization by implementing readObject().

Be aware of the following when using serialization:

  • Java objects may be bundled with the serialized bit-blob.

  • Any basic type (int, char, etc.) is automatically serialized with the object and is available when deserialized.

  • Objects marked transient are not serialized with the object and are not available when deserialized.

  • Objects that are not marked transient must implement java.lang.Serializable. They are converted to bit-blobs along with the original object.

    Note

    If objects are not marked with the transient keyword and do not implement java.lang.Serializable, a NotSerializable Exception is thrown when writeobject() is called.

When should a developer mark a member variable as transient? If an object is large, do so because it is not a good candidate for object serialization. If the object represents a resource that cannot be reconstructed on a remote machine—for example, database connections, or if you consider the field data to be sensitive—mark the variable as transient.

RMI-IIOP uses object serialization for passing values via a Remote Method Invocation. When an object is passed as a parameter, the stub is copied via pass-by- reference. Stubs are also serializable and can be passed over the wire as bit-blobs.

In summary, all Java basic primitives are passed by value when invoking methods remotely. If an object is passed over the network by value, the object must implement java.lang.Serializable. If an object is passed by reference, it must be a remote object and must implement java.rmi.Remote. In this case, a stub for the remote object is serialized and passed to the remote host.

Note

Refer back to the Widget application in Chapter 2 for a review of the concepts mentioned here.




.NET & J2EE Interoperability
Microsoft .NET and J2EE Interoperability Toolkit (Pro-Developer)
ISBN: 0735619220
EAN: 2147483647
Year: 2004
Pages: 101
Authors: Simon Guest

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net