work from which the bytecodes for the implementation of that class can be found. When the
object is being deserialized, object serialization will first look at the set of classes available
locally to see whether the actual class of the object can be found, and if so will use that local
class. But if the class is not on the local machine, the code for the class will be obtained (if
possible) from the source indicated in the serialization stream, and it will be loaded into the
receiving JVM and used to reconstruct the object.
To see how this works, let's go back to the getRoster() method of our StatRecorder inter-
face. All that the StatReporterImpl instance knows about the return value of this method is
that it is a List of Player objects. If this comes from our StatRecorderImpl , what is sent
is a copy of a LinkedList of PlayerImpl objects. The serialized stream is annotated with
both the actual class of the objects in the stream and a location from which code has been
made available if needed. When the StatReporterImpl process deserializes the return value,
it should have no trouble finding a LinkedList implementation, as this is part of the standard
Java runtime. But if it does not have a PlayerImpl class, it can obtain the right code over the
network at the location indicated in the serialized stream. This code will be loaded and used
for the objects that are being reconstructed.
Ensuring that the needed implementation code can be downloaded when needed to pass ob-
jects by value in RMI requires some work on the actual configuration of the runtime system.
This has little to do with the programming of an application using RMI, but everything to do
with the running of such programs.
Just as the classpath determines where the Java virtual machine will look to dynamically
load code during runtime, there is a system property that determines how the serialized stream
produced will be annotated to tell a receiving process where to look for classes needed for
deserializing that stream. This property, which has the name java.rmi.server.codebase ,
should be set to a URL that is accessible from the client and that is the root of a hierarchy of
classes (or a .jar file) that contains the code that may need to be downloaded. For example, to
ensure that our PlayerImpl class is available to clients, we could start the program that con-
tains the StatRecorderImpl with the system property:
assuming that we were running something that could serve files from a URL (such as a web
server) on the machine statServer.com , and that in the directories for that web server was a
directory codeserver that contained the codedl.jar file that in turn contained all of the classes
that might need to be downloaded by a client of the StatServerImpl . It is good practice to