CONTENTS | PREV | NEXT | Java Remote Method Invocation |
Call and return data in RMI calls are formatted using the Java Object Serialization protocol. Each method invocation's CallData is written to a Java object output stream that contains the ObjectIdentifier (the target of the call), an Operation (a number representing the method to be invoked), a Hash (a number that verifies that client stub and remote object skeleton use the same stub protocol), followed by a list of zero or more Arguments for the call.In the JDK1.1 stub protocol the Operation represents the method number as assigned by rmic, and the Hash was the stub/skeleton hash which is the stub's interface hash. As of the Java 2 stub protocol (Java 2 stubs are generated using the
-v1.2
option withrmic
), Operation has the value -1 and the Hash is a hash representing the method to call. The hash is described in the section "The RemoteRef Interface".
A ReturnValue of an RMI call consists of a return code to indicate either a normal or exceptional return, a UniqueIdentifier to tag the return value (used to send a
CallData:
ObjectIdentifier Operation Hash Argumentsopt
ObjectIdentifier:
ObjectNumber UniqueIdentifier
UniqueIdentifier:
Number Time Count
Arguments:
Value
Arguments Value
Value:
Object
Primitive
DGCAck
if necessary) followed by the return result: either the Value returned or the Exception thrown.
ReturnValue:
0x01 UniqueIdentifier Valueopt
0x02 UniqueIdentifier Exception
Note - ObjectIdentifier, UniqueIdentifier, and EndpointIdentifier are not written out using default serialization, but each uses its own special write method (this is not the writeObject method used by object serialization); the write method for each type of identifier adds its component data consecutively to the output stream.
RMI overrides theannotateClass
andresolveClass
methods ofObjectOutputStream
andObjectInputStream
respectively. Each class is annotated with the codebase URL (the location from which the class can be loaded). In theannotateClass
method, the classloader that loaded the class is queried for its codebase URL. If the classloader is non-null
and the classloader has a non-null
codebase, then the codebase is written to the stream using theObjectOutputStream.writeObject
method; otherwise anull
is written to the stream using thewriteObject
method. Note: as an optimization, classes in the "java
" package are not annotated, since they are always available to the receiver.The class annotation is resolved during deserialization using the
ObjectInputStream.resolveClass
method. TheresolveClass
method first reads the annotation via theObjectInputStream.readObject
method. If the annotation, a codebase URL, is non-null
, then it obtains the classloader for that URL and attempts to load the class. The class is loaded by using ajava.net.URLConnection
to fetch the class bytes (the same mechanism used by a web browser's applet classloader).