don't want to load code without the protection of a security manager, programs utilizing RMI
should always be run with a security manager. We will talk more about this later, but adding
lines like the first two in exportRecorder() ought to be a reflex for anyone using RMI.
The next line finds an instance of an RMI Registry object running on the local node. These
registries are simple naming systems, allowing an RMI server to register itself under a name
so that clients of the server can find it. Only objects on a (physical) machine can register with
the registry on that machine, [ 30 ] but clients on other machines can look up values in registries
on any machine they can find. This call assumes that some registry is running in the environ-
ment on which the server is going to run. The standard rmiregistry is shipped as part of the
Java Development Kit.
There is nothing special about the RMI registry, other than that it is a well-known place where
proxy objects can be stored and found. Any remotely accessible Java object could allow prox-
ies to be registered and then hand those proxy objects out to others. The registry is a boot-
strapping mechanism that is part of the standard Java platform, and therefore is known to be
available. But others can be (and have been) written.
The next line is where most of the heavy lifting gets done. Here is where we export our server
to the RMI runtime, using a call to UnicastRemoteObject.export() . In this call, we indic-
ate which object we wish to export and the number of the port on which we want the object to
receive calls (we also could have specified a port of 0 , in which case the RMI runtime would
have picked a port for us). The RMI runtime will create a dynamic proxy object that knows
how to contact that port, and the RMI runtime itself will listen on that port for network mes-
sages, forward calls to the remotely accessible methods, and return the values of those calls to
the proxy object. The proxy object is returned from the export call. This proxy object is itself
an instance of a class that implements both the Serializable interface and any other inter-
face that extends Remote and is implemented by the implementation class. In this case, that
would be the StatRecorder interface.
The idea is that we can ship a serialized form of the proxy object over the network, where it
can be deserialized and act as a stand-in for our StatRecorder instance. The client that has
received the proxy can make calls on that proxy that will be packaged up and sent over the
network to our StatRecorderImpl . Responses will be shipped back to the proxy object that
will return those responses to the client.
Finally, we register this proxy object with the local registry, using the name Recorder so that
clients wanting to send game results can find it. These clients will need to know the name or
network address of the machine on which the StatRecorderImpl is running, but if they are