To accomplish transparent transmission of objects from one address space to another, the technique of object serialization (designed specifically for the Java language) is used. Object serialization is described in this chapter only with regard to its use for marshaling primitives and objects. For complete details, see the RMI system's companion specification, Object Serialization in the Java System.
Another technique, called dynamic stub loading, is used to support client-side stubs which implement the same set of remote interfaces as a remote object itself. This technique, used when a stub of the exact type is not already available to the client, allows a client to use the Java language's built-in operators for casting and type-checking.

A remote method invocation from a client to a remote server object travels down through the layers of the RMI system to the client-side transport, then up through the server-side transport to the server.
A client invoking a method on a remote server object actually makes use of a stub or proxy for the remote object as a conduit to the remote object. A client-held reference to a remote object is a reference to a local stub. This stub is an implementation of the remote interfaces of the remote object and forwards invocation requests to that server object via the remote reference layer.
The remote reference layer is responsible for carrying out the semantics of the invocation. For example the remote reference layer is responsible for determining whether the server is a single object or is a replicated object requiring communications with multiple locations. Each remote object implementation chooses its own remote reference semantics-whether the server is a single object or is a replicated object requiring communications with multiple locations.
Also handled by the remote reference layer are the reference semantics for the server. The remote reference layer, for example, abstracts the different ways of referring to objects that are implemented in (a) servers that are always running on some machine, and (b) servers that are run only when some method invocation is made on them. At the layers above the remote reference layer, these differences are not seen.
The transport is responsible for connection set-up, connection management, and keeping track of and dispatching to remote objects (the targets of remote calls) residing in the transport's address space.
In order to dispatch to a remote object, the transport forwards the remote call up to the remote reference layer. The remote reference layer handles any server-side behavior that needs to be done before handing off the request to the server-side skeleton. The skeleton for a remote object makes an up-call to the remote object implementation which carries out the actual method call.
The return value of a call is sent back through the skeleton, remote reference layer and transport on the server side, and then up through the transport, remote reference layer and stub on the client side.
A stub for a remote object is the client-side proxy for the remote object. Such a stub implements all the interfaces that are supported by the remote object implementation. A client-side stub is responsible for:
The Remote Reference Layer
The remote reference layer deals with the lower level transport interface. This layer is also responsible for carrying out a specific remote reference protocol which is independent of the client stubs and server skeletons.
In a corresponding manner, the server-side component implements the specific remote reference semantics prior to delivering a remote method invocation to the skeleton. This component, for example, could handle ensuring atomic multiple delivery by communicating with other servers in the replica group.
The remote reference layer transmits data to the transport layer via the abstraction of a stream-oriented connection. The transport takes care of the implementation details of connections. Although connections present a streams-based interface, a connectionless transport may be implemented beneath the abstraction.
The transport for the RMI system consists of four basic abstractions:
To accomplish reference-counting garbage collection, the RMI runtime keeps track of all live references within each Java virtual machine. When a live reference enters a Java virtual machine its reference count is incremented. The first reference to an object sends a "referenced" message to the server for the object. As live references are found to be unreferenced in the local virtual machine, their finalization decrements the count. When the last reference has been discarded an unreferenced message is sent to the server. Many subtleties exist in the protocol, most related to maintaining the ordering of referenced and unreferenced messages to insure the object is not prematurely collected.
When a remote object is not referenced by any client, the RMI runtime refers to it using a weak reference. The weak reference allows the Java virtual machine's garbage collector to discard the object if no other local references to the object exist. The distributed garbage collection algorithm interacts with the local Java virtual machine's garbage collector in the usual ways by holding normal or weak references to objects. As in the normal object life-cycle
finalize will be called after the garbage collector determines that no more references to the object exist.As long as a local reference to a remote object exists, it cannot be garbage collected and it may be passed in remote calls or returned to clients. Passing a remote object adds the client or server to which it was passed to the referenced set. A remote object needing unreferenced notification must implement the
java.rmi.server.Unreferenced interface. When those references no longer exist, unreferenced will be invoked. unreferenced is called when the set of references is found to be empty so it may be called more than once. Remote objects are only collected when no more references, either local or remote, still exist.Note that if there exists a network partition between a client and remote server object, it is possible that premature collection of the remote object will occur (since the transport may think that the client crashed). Because of the possibility of premature collection, remote references cannot guarantee referential integrity; in other words, it is always possible that a remote reference may in fact not refer to an existing object. An attempt to use such a reference will generate a
RemoteException which must be handled by the application.
However, the JDK 1.0 security manager does not regulate resource consumption, so the current RMI system has no mechanisms available to prevent classes loaded from abusing resources. In addition, it is possible that methods invoked by the system, for example the hashCode, equals, and toString methods, might contain trojan horses. As new security manager mechanisms are developed, RMI will use them.
applet environment, the AppletSecurityManager and AppletClassLoader are used exclusively. RMI uses only the established security manager and class loader. In this environment remote object stubs and parameter and return object classes can be loaded only from the applet host or its designated code base hosts. This requires that applet developers install the appropriate classes on the applet host.
When a server is passed a remote object for which it has no corresponding stub code, it may also be passed the location from which the classes for that remote object may be loaded. Two properties control if and from where the stub class can be loaded.
java.rmi.server.ClientClassDisable controls whether the URL's supplied by clients are used, if set to true, URL's from clients are ignored and stub classes are loaded using the stub class base.
java.rmi.server.StubClassBase defines the URL from which stub classes will be loaded. This is the URL that is passed along with remote object references so clients will know from where to load stub classes.
StubClassLoader to load the classes. If it succeeds those classes will be subject to the current security manager and any classes the stub needs will be loaded and then regulated by that security manager. If the security manager disallows creating the class loader, the stub will be loaded using the default Class.forName mechanism. Thus, a server may define its own policies via the security manager and stub loader and the RMI system will operate within them.
RMI generalizes this technique to load the exact stub code (in the Java language's architecture neutral bytecode format) at run-time to handle method invocations on a remote object. This mechanism, called dynamic stub loading, exploits the Java mechanism for downloading code. Normally stubs can be dynamically loaded from the local file system, in which case there are no security manager restrictions. However, when loaded from the network, those classes loaded must be restricted by the security manager.
Dynamic stub loading is used only when code for a needed stub is not already available. The argument and return types specified in the remote interfaces are made available using the same mechanism. Loading arbitrary classes into clients or servers presents a potential security problem which is addressed below.
In this scheme, client-side stub code is generated from the remote interfaces of the implementation class and support the same set of remote interfaces. Such stub code resides on the server's host (or perhaps another location), and can be downloaded to the client on demand (if the correct stub code is not already available to the client). Stub code for a remote implementation could be generated on-the-fly at the remote site and shipped to the client or could be generated on the client-side from the list of remote interfaces supported by the remote implementation.
Dynamic stub loading employs three mechanisms: a Java class loader, a security manager and the object serialization system. When a remote object reference is passed as a parameter or as the result of a method call, the marshal stream that transmits the reference includes information indicating where the stub class for the remote object can be loaded from, if its URL is known.
A marshal stream is implemented by an underlying object serialization stream. These streams provide an opportunity to embed information for each class and object that is transmitted. When transmitting class information for a remote object being marshaled, a marshal stream embeds a URL that specifies where the stub code resides. Thus, when a reference to a remote object is unmarshaled at the destination site, the marshal stream can locate and load the stub code (via the class loader, checked by the security manager) so that the correct stub is available to the client.
In a related scenario, the Applet may create its own remote objects and pass them to the RMI service. If the classes are all known to the service, there is no difference from the previous scenario. If, however, the applet uses classes unknown to the server to create new remote objects and passes them to the service, the service will need to load those classes. If the service is configured with a security manager, it may load the classes from the same location the Applet did.
Using the usual class loading mechanisms, classes can either be loaded from the local file system or from a Web server.
Classes on the local file system can be found with the CLASSPATH environment variable. These classes are not subject to the restrictions imposed by the security manager and are assumed to be trusted. Either or both the applications and servers can load classes from the local file system.
Alternatively, a class loader can be used to load stubs from a Web server. The RMI Stub class loader is similar to the Applet class loader and is used to load classes from Web servers as needed by RMI. In the Stub class loader, classes will not be loaded from a Web server unless a security manager is present and when loaded the classes are subject to the security manager restrictions. As with other class loaders, any stub class that refers to other classes will use the stub class loader and thus be subject to the security manager restrictions even if the referred-to classes are found on the local file system.
An application's need to dynamically load classes is always satisfied first from the local file system. If not found locally, the RMI runtime needs to know where to find the class. Two mechanisms are used by the RMI runtime. As each remote object is passed to the application, the server, if configured to do so, may include the URL of the stub class. This URL is used to load the stubs. If not supplied, the RMI runtime uses a property configured by the application to load the stub. If this stub class base is not defined, the load will fail and the method invocation will fail with an exception. So, either the server must tell the client where the stubs can be found, or the application itself must be configured to know. The application may disable the loading of stubs and force stubs to be loaded only from the locally defined stub class base.
For example, an application will usually load its initial classes locally, since (unlike Applets) there is no built-in support for loading network classes. The remote objects used by the application will again come from a server. Unless the application is configured with a security manager, stubs will not be loaded even if the URL is supplied by the server. This keeps the application safe even from the server.
In another scenario, the application can use the RMI supplied security manager and stub loader to allows stubs to be loaded from the URL supplied by the server. This allows more flexibility and extensibility.
Similar to the last Applet example, if the application creates and exports its own remote objects, then it will need to supply the URL of those classes to the server(s). In many cases, those remote object classes will be loaded from a Web server and those URLs are passed on as needed. If however, the remote object classes are local to the application system, some provision will need to be made for those classes to be available via a Web server and the stub class base to be configured so that the stubs of those remote objects can be loaded by servers. The easiest to manage is to put the classes on a Web server and have all the applications and servers load them from there.
The typical closed system scenario has the server configured to load no classes. The services it provides are defined by remote interfaces that are all local to the server machine. The server needs no security manager and will not load classes even if clients send along the URL. If clients send remote objects for which the server does not have stub classes, those method invocations will fail when the request is unmarshaled, and the client will receive an exception.
The more open server system will define its stub class base so that stubs for the remote objects it exports can be loaded by clients and so that the server can load stubs when needed for remote objects supplied by clients. The server will have both a security manager and stub class loader which protect the server.
A somewhat more cautious server can use the property
java.rmi.server.ClientClassDisable to disable the loading of classes from client supplied URLs. It can still load those classes from clients as well as the stub classes need by its clients.The JDK 1.0 security manager does not regulate resource consumption, so the current RMI system has no mechanisms available to prevent classes loaded from abusing resources. As new security manager mechanisms are developed to control resource use, RMI will use them.