A Multiple-Deployment Scenario How Dynamic Classloading Works

stressful for IT and would allow for a much greater degree of testing for the new functionality. No matter how thoroughly you test an application, theres still a substantial risk when you roll it out to an enterprise. Dynamic classloading lets you do exactly this. When you launch the new servers, and bind in the instances of Account2 , the old client application will receive a serialized instance of the new stub. Because the old application doesnt have the appropriate classes locally, it will download them from the URL. The cast will succeed, and the server will be upgraded in a way thats totally transparent to the client application. The same idea also applies for less drastic upgrades. For example, changing a supporting class, such as a socket factory, can be instantly accomplished if either the class name changes, or if the old class isnt actually deployed on the clients filesystem.

19.3.2 A Multiple-Deployment Scenario

The first scenario was about gradually rolling out an application change to the client side. Our second scenario is similar, but involves gradually rolling out updated server applications without causing problems for existing installations. In this scenario, we could wind up with two different versions of the same server bound into a single naming service. That is: Server 1 Uses a version of the server class that implements the Account interface as of 0210 Server 2 Uses a version of the server class that implements the Account interface as of 0610 In this scenario, we cannot put the stub classes on the naming services classpath. The bootstrap classloader will load only one class definition from the filesystem. Regardless of which is loaded, one of the servers wont be able to bind its stubs into the naming service. The solution for this problem is simple: dont install any classes on the naming services classpath, and give the two applications different codebase URLs. The RMI classloading algorithm will load both classes dynamically and use them correctly. This will happen automatically. Marshalled Objects and Codebases The idea that the server can download classes, as well as instances, leads to some interesting problems with serialization. Suppose, for example, that a client application needs to implement a simple persistence layer. One natural way to do this is via serialization: the client application can create an instance of FileInputStream and use serialization to make persistent copies of the objects. This can break if the instances stored in the file are instances of class es that the client application downloaded e.g., instances of classes not on the client applications classpath. When the client tries to deserialize the instances from the file, it needs the class definitions for the instances in the file. If the class definitions arent on the clients classpath, deserialization will fail because the ordinary serialization and deserialization algorithms dont store a codebase property. One solution to this is to use instances of MarshalledObject , which we previously discussed in Chapt er 17 . Recall that MarshalledObject is a class with instances that contain a single serialized instance of another class. In Chapt er 17 , I stated that MarshalledObject uses RMIs customized version of serialization to store data. This means that any instance serialized into an instance of MarshalledObject has a codebase, and when the instance is deserialized using get , the class is retrieved from the codebase location if necessary. Thus, if you want to implement a simple client-side persistence layer using serialization for an RMI application, you should use the following three-step procedure: 1. Create an instance of FileInputStream . 2. Serialize the instances you want to store into instances of MarshalledObject by passing them as arguments to MarshalledObject s constructor. 3. Serialize the instances of MarshalledObject to the instance of FileInputStream . This is more complicated than directly serializing the instances to a file, but will help to guarantee that the serialized instances can be read back in later.

19.4 The Class Server