THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

be run securely.


Many environments can use the basic infrastructure just described. A compute farm that uses a large number
of computers to render animation can use such a system to feed those computers images to be rendered, sound
computations, and other tasks. This simple example needs some hardening to be used in other situations,
especially when Task objects could not be trusted to be friendly. All you need is a Java virtual machine at
both ends of the network.


UnicastRemoteObject references are for remote services that are started by the user or system. You can
use java.rmi.activation.Activatable for references to remote objects that you want to be started
automatically when they are first needed.


Because of the dangers inherent in running downloaded code, RMI requires that a security manager be
installed. The RMISecurityManager class is a very conservative security manager that you can install to
prevent unauthorized access to your system, or you can provide your own security manager.


Your server class may not be able to extend an RMI server class because your class must extend a different
class. For example, an applet class must extend Applet and so cannot extend UnicastRemoteObject.
You can create servers that do not extend UnicastRemoteObject by having your class's constructor
invoke a static method:


public class SnazzyApplet extends Applet
implements SnazzyRemote
{
public SnazzyApplet() throws RemoteException {
UnicastRemoteObject.exportObject(this);
}
// ... implement SnazzyRemote and Applet methods ...
}


Classes are downloaded from client to server (or server to client) only if they are needed. Classes will often be
known on both sides. For example, BigDecimal is part of the core, so both the client and the server already
know about it and it will not be downloaded. User-defined classes are treated in the same wayif both the client
and server have a class installed, it will not be downloaded across the network.


Arguments and return values of remote methods are handled somewhat differently from those of local
methods. RMI passes arguments and return values by using object serialization (see page 549). When a remote
reference is passed as an argument or return value, the receiver will get a reference to the same remote object
that was passed. This is how local references act in local methodsan object reference refers to the same object
in both the invoking code and the invoked method. Primitive types, too, are passed in the same way locally
and remotely; the receiver gets a copy of the value.


References to local objects must be passed differently. Local objects are not designed to deal with partial
failures, so it is not possible to pass across the network a remote reference to a local object. Local objects are
instead passed by a deep copy made by serialization. Any remote references contained within the object or in
any part of the graph of objects it denotes will be passed as described earlier. All other parts of the graph will
be serialized on the sender's system and deserialized on the receiver's. Changes made on one side will not be
visible to the other side, because each side has its own local copy of the object.


The RMI registry provides a simple naming system to store remote references for bootstrapping your clients.
This is not a full naming system, but it will let you store objects that register or find top-level services. The
registry is accessed via the Naming class.

Free download pdf