8 Stub/Skeleton Interfaces
- The
RemoteStub
Class - The
RemoteCall
Interface - The
RemoteRef
Interface - The
ServerRef
Interface - The
Skeleton
Interface - The
Operation
Class
This section contains the interfaces and classes used by the stubs
and skeletons generated by the rmic
stub compiler.
8.1 The RemoteStub
Class
The java.rmi.server.RemoteStub
class is the common
superclass for stubs of remote objects. Stub objects are surrogates that
support exactly the same set of remote interfaces defined by the actual
implementation of a remote object.
package java.rmi.server;
public abstract class RemoteStub extends java.rmi.RemoteObject {
protected RemoteStub() {...}
protected RemoteStub(RemoteRef ref) {...}
protected static void setRef(RemoteStub stub, RemoteRef ref) {...}
}
The first constructor of RemoteStub
creates a stub with
a null
remote reference. The second constructor creates a
stub with the given remote reference, ref.
The setRef
method is deprecated (and unsupported) as of
the Java 2 SDK, Standard Edition, v1.2.
8.1.1 Type Equivalency of Remote Objects with a Stub Class
Clients interact with stub (surrogate) objects that have exactly the same set of remote interfaces defined by the remote object's class; the stub class does not include the non-remote portions of the class hierarchy that constitutes the object's type graph. This is because the stub class is generated from the most refined implementation class that implements one or more remote interfaces. For example, if C extends B and B extends A, but only B implements a remote interface, then a stub is generated from B, not C.
Because the stub implements the same set of remote interfaces as the remote object's class, the stub has the same type as the remote portions of the server object's type graph. A client, therefore, can make use of the built-in Java programming language operations to check a remote object's type and to cast from one remote interface to another.
Stubs are generated using the rmic
compiler.
8.1.2 The
Semantics of Object Methods Declared final
The following methods are declared final
in the
java.lang.Object
class and therefore cannot be overridden
by any implementation:
getClass
notify
notifyAll
wait
The default implementation for getClass
is appropriate
for all objects written in the Java programming language, local or
remote; so, the method needs no special implementation for remote
objects. When used on a remote stub, the getClass
method
reports the exact type of the stub object, generated by
rmic
. Note that stub type reflects only the remote
interfaces implemented by the remote object, not that object's local
interfaces.
The wait
and notify
methods of
java.lang.Object
deal with waiting and notification in the
context of the Java programming language's threading model. While use of
these methods for remote stubs does not break the threading model, these
methods do not have the same semantics as they do for local objects
written in the Java programming language. Specifically, these methods
operate on the client's local reference to the remote object (the stub),
not the actual object at the remote site.
8.2 The RemoteCall
Interface
The interface RemoteCall
is an abstraction used by the
stubs and skeletons of remote objects to carry out a call to a remote
object.
Note: The RemoteCall
interface is
deprecated as of the Java 2 SDK, Standard Edition, v1.2. The 1.2 stub
protocol does not make use of this interface anymore. As of the Java 2
SDK, Standard Edition, v1.2, stubs now use the new invoke
method which does not require RemoteCall
as a
parameter.
package java.rmi.server;
import java.io.*;
public interface RemoteCall {
ObjectOutput getOutputStream() throws IOException;
void releaseOutputStream() throws IOException;
ObjectInput getInputStream() throws IOException;
void releaseInputStream() throws IOException;
ObjectOutput getResultStream(boolean success)
throws IOException, StreamCorruptedException;
void executeCall() throws Exception;
void done() throws IOException;
}
The method getOutputStream
returns the output stream
into which either the stub marshals arguments or the skeleton marshals
results.
The method releaseOutputStream
releases the output
stream; in some transports this will release the stream.
The method getInputStream
returns the
InputStream
from which the stub unmarshals results or the
skeleton unmarshals parameters.
The method releaseInputStream
releases the input stream.
This will allow some transports to release the input side of a
connection early.
The method getResultStream
returns an output stream
(after writing out header information relating to the success of the
call). Obtaining a result stream should only succeed once per remote
call. If success is true
, then the result to be
marshaled is a normal return; otherwise the result is an exception.
StreamCorruptedException
is thrown if the result stream has
already been obtained for this remote call.
The method executeCall
does whatever it takes to execute
the call.
The method done
allows cleanup after the remote call has
completed.
8.3 The RemoteRef
Interface
The interface RemoteRef
represents the handle for a
remote object. Each stub contains an instance of RemoteRef
that contains the concrete representation of a reference. This remote
reference is used to carry out remote calls on the remote object for
which it is a reference.
package java.rmi.server;
public interface RemoteRef extends java.io.Externalizable {
Object invoke(Remote obj,
java.lang.reflect.Method method,
Object[] params,
long opnum)
throws Exception;
RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum,
long hash) throws RemoteException;
void invoke(RemoteCall call) throws Exception;
void done(RemoteCall call) throws RemoteException;
String getRefClass(java.io.ObjectOutput out);
int remoteHashCode();
boolean remoteEquals(RemoteRef obj);
String remoteToString();
}
The invoke(Remote,Method,Object[],long)
method delegates
method invocation to the stub's (obj) remote reference and
allows the reference to take care of setting up the connection to the
remote host, marshaling some representation for the method and
parameters, params, then communicating the method invocation to
the remote host. This method either returns the result of the method
invocation on the remote object which resides on the remote host or
throws a RemoteException
if the call failed or an
application-level exception if the remote invocation throws an
exception. Note that the operation number, opnum, represents a
hash of the method signature and may be used to encode the method for
transmission.
The method hash to be used for the opnum parameter is a
64-bit (long) integer computed from the first two 32-bit values of the
message digest of a particular byte stream using the National Institute
of Standards and Technology (NIST) Secure Hash Algorithm (SHA-1). This
byte stream contains a string as if it was written using the
java.io.DataOutput.writeUTF
method, consisting of the
remote method's name followed by its method descriptor (see The Java
Virtual Machine Specification (JVMS) for a description of method
descriptors).
For example, if a method of a remote interface has the following name and signature:
void myRemoteMethod(int count, Object obj, boolean flag)
the string containing the remote method's name and descriptor would be the following:
myRemoteMethod(ILjava/lang/Object;Z)V
The 64-bit hash value is the little-endian composition of an eight
byte sequence where the first four bytes are the first 32-bit value of
the message digest in big-endian byte order and the last four bytes are
the second 32-bit value of the message digest in big-endian byte order.
For example, if the first two 32-bit values of the message digest are
0xB0B1B2B3
and 0xB4B5B6B7
, then the hash value
would be 0xB7B6B5B4B3B2B1B0
.
Note: The methods
newCall(RemoteObject,Operation[],int,long)
,
invoke(RemoteCall)
, and done(RemoteCall)
are
deprecated as of the Java 2 SDK, Standard Edition, v1.2. The stubs
generated by rmic
using the 1.2 stub protocol version do
not use these methods any longer. The sequence of calls consisting of
newCall
, invoke
, and done
have
been replaced by a new invoke
method that takes a
Method
object as one of its parameters.
The method newCall
creates an appropriate call object
for a new remote method invocation on the remote object obj.
The operation array, op, contains the available operations on
the remote object. The operation number, opnum, is an index
into the operation array which specifies the particular operation for
this remote call. The interface hash is a 64-bit value used to
enforce compatibility between a stub and skeleton using the v1.1 stub
protocol. The interface hash is computed from the first two 32-bit
values of the message digest of a particular byte stream using SHA-1.
This byte stream contains data as if it was written using the
writeInt
and writeUTF
methods of the interface
java.io.DataOutput
, consisting of the following items:
- (
int
) stub version number, always 1 - for each remote method, in order of operation number:
- (UTF-8) remote method name
- (UTF-8) remote method descriptor (see The Java Virtual Machine Specification)
- for each declared exception, in lexicographic order of binary name:
- (UTF-8) the name of the exception class
The interface hash value is composed from the message digest in the
same manner as described above for the method hash used in the
invoke
method.
The method invoke(RemoteCall)
executes the remote call.
invoke
will raise any "user" exceptions which should pass
through and not be caught by the stub. If any exception is raised during
the remote invocation, invoke
should take care of cleaning
up the connection before raising the "user exception" or
RemoteException
.
The method done
allows the remote reference to clean up
(or reuse) the connection. done
should only be called if
the invoke
call returns successfully (non-exceptionally) to
the stub.
The method getRefClass
returns the nonpackage-qualified
class name of the reference type to be serialized onto the stream
out.
The method remoteHashCode
returns a hashcode for a
remote object. Two remote object stubs that refer to the same remote
object will have the same hash code (in order to support remote objects
as keys in hashtables). A RemoteObject
forwards a call to
its hashCode
method to the remoteHashCode
method of the remote reference.
The method remoteEquals
compares two remote objects for
equality. Two remote objects are equal if they refer to the same remote
object. For example, two stubs are equal if they refer to the same
remote object. A RemoteObject
forwards a call to its
equals
method to the remoteEquals
method of
the remote reference.
The method remoteToString
returns a String
that represents the reference of this remote object.
8.4 The ServerRef
Interface
The interface ServerRef
represents the server-side
handle for a remote object implementation.
package java.rmi.server;
public interface ServerRef extends RemoteRef {
RemoteStub exportObject(java.rmi.Remote obj, Object data)
throws java.rmi.RemoteException;
String getClientHost() throws ServerNotActiveException;
}
The method exportObject
finds or creates a client stub
object for the supplied Remote
object implementation
obj.The parameter data contains information necessary
to export the object (such as port number).
The method getClientHost
returns the host name of the
current client. When called from a thread actively handling a remote
method invocation, the host name of the client invoking the call is
returned. If a remote method call is not currently being service, then
ServerNotActiveException
is called.
8.5 The Skeleton
Interface
The interface Skeleton
is used solely by the
implementation of skeletons generated by the rmic
compiler.
A skeleton for a remote object is a server-side entity that dispatches
calls to the actual remote object implementation.
Note: The Skeleton
interface was
deprecated as of the Java 2 SDK, Standard Edition, v 1.2. Every 1.1 (and
version 1.1 compatible skeletons generated in 1.2 using
rmic -vcompat
, the default) skeleton class generated by the
rmic
stub compiler implements this interface. Skeletons are
no longer required for remote method call dispatch as of Java 2 SDK,
Standard Edition, v1.2-compatible versions. To generate stubs that are
compatible with 1.2 or later versions, use the command rmic
with the option -v1.2
.
package java.rmi.server;
public interface Skeleton {
void dispatch(Remote obj, RemoteCall call, int opnum, long hash)
throws Exception;
Operation[] getOperations();
}
The dispatch
method unmarshals any arguments from the
input stream obtained from the call object, invokes the method
(indicated by the operation number opnum) on the actual remote
object implementation obj, and marshals the return value or
throws an exception if one occurs during the invocation.
The getOperations
method returns an array containing the
operation descriptors for the remote object's methods.
8.6 The Operation
Class
The class Operation
holds a description of a method in
the Java programming language for a remote object.
Note: The Operation
interface is
deprecated as of the Java 2 SDK, Standard Edition, v1.2. The 1.2 stub
protocol no longer uses the old RemoteRef.invoke
method
which takes an Operation
as one of its arguments. As of the
Java 2 SDK, Standard Edition, v1.2, stubs now use the new
invoke
method which does not require Operation
as a parameter.
package java.rmi.server;
public class Operation {
public Operation(String op) {...}
public String getOperation() {...}
public String toString() {...}
}
An Operation
object is typically constructed with the
method signature.
The method getOperation
returns the contents of the
operation descriptor (the value with which it was initialized).
The method toString
also returns the string
representation of the operation descriptor (typically the method
signature).