The Artima Developer Community
Sponsored Link

Object Mobility in the Jini Environment
Simplify the Installation and Configuration of Jini Applications
by Frank Sommers
First Published in JavaWorld, January 2001

<<  Page 4 of 9  >>


Codebase Annotation

At this point, you have two sides of a story. On the one hand, the JVM's class loaders can find and load a class from their codebases, if they are given that class's name. On the other hand, you've seen that objects can be written to a stream and transported across VMs, and that object streams contain instance data to recreate the object as well as a descriptor of the object's class.

A complete story would need to connect these two sides. Given a class's name from the descriptor found in the serialized stream, the VM still needs to know where it should load the actual class from. Once it has that information, the VM can create a class loader with the codebase pointing to that location, load the class, link it to the current execution environment, and initialize its class data (i.e., set its static fields). Finally, the VM could use the data contained in the serialized object stream to create an instance of the class and initialize the object's instance data.

One solution would be to save the entire Class object corresponding to the serializable object's class instead of saving just a descriptor. However, that solution has two major downsides.

First, it would add significant overhead to each serial object stream. Because serialization means writing to the object stream, possibly transporting the object stream through a network, and then reading the stream, all these would take longer and would require more resources to perform with this overhead.

The second downside has to do with class evolution. Serializing an object means that it can survive the VM instance that created it, which implies that it is stored persistently across VM instances for longer periods of time. In this way, serialized objects are a persistent storage mechanism.

In practice, Java classes evolve over time: new fields might be added, methods may be implemented anew, bugs are discovered and fixed, and so on. With each of these changes, the class is altered. It would be unfortunate if you could not use information stored in serialized versions of an object with newer class versions. Good programming practice dictates that classes evolve in such a way that they preserve compatibility with older versions (i.e., that they be backwards compatible). Decoupling serialized objects from their corresponding Class objects allows for backwards-compatible class evolution, since newer class versions can still load serialized instance data from objects defined originally with an older version.

A better solution would be to tell the VM where it can download the object's class from. One way to do this is to stamp the code location for the class onto the serialized object stream -- in other words, to annotate the serialized object with the codebase URL. This method facilitates dynamic code mobility, because the VM can decide at runtime where it should download the classes from. This is also the fundamental technique used by Java RMI (see the Java Remote Method Invocation Specification, Chapter 10.3.1).

Figure 3. Codebase annotation on the serialized object stream

The RMI runtime mechanism provides a special output stream, which, in addition to serializing the object, does the following:

  1. It annotates the location of the object's class to the serialized stream.
  2. When the object to be serialized is a remote object (i.e., when it implements java.rmi.Remote), instead of serializing the object itself, its stub is serialized.

The codebase is specified with the following property to the VM:


The codebase property is a space-separated list of URLs. When deserializing an RMI stub annotated with the codebase, the RMI runtime will create a class loader for each codebase URL specified in this list. (The class java.rmi.RMIClassLoader is a factory of class loaders that facilitates this process.)

Jini services that use RMI to communicate between the service object and the service typically register their stubs in lookup services. (Recall that the RMI runtime replaces the object with its stub in the serialized stream.) This ensures that the RMI runtime annotates the serialized stub with the codebase for class downloading, and that this information will be available to clients of the service. The clients will use these URLs to download needed classfiles. The ability to download code is a key RMI feature. Jini builds on RMI's semantics of mobile code (see the Jini Architecture Specification, Section AR2.1.3).

<<  Page 4 of 9  >>

Sponsored Links

Copyright © 1996-2018 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use