Our Actual Launch Code

All of this helps to motivate the idea that the next level of thinking about your distributed application should center on managing the server lifecycle. That is, the next level of distributed application design centers on the following three questions: • When should servers be launched? • When should servers be shut down? • When should servers save their state to a persistent store? These are especially pertinent questions in the bank example. We potentially have millions of server objects, but only a small percentage of the accounts are active at any given time. And, once an account has been active, it is unlikely to be active again for quite some time. After all, very few people directly access their bank account more than once per day. With this discussion behind us, it should be clear that launch code which is the first step towards managing the server lifecycle does not belong inside the server objects.

9.2 Our Actual Launch Code

Launch code typically consists of two things: a set of batch files [ 1] that are run from a command line and start one or more Java applications running, and Java code. In our case, these are very simple. There are two batch files: one to launch the servers and one to run the client application. The server batch file consists of the following code: [ 2] [ 1] In Unix terminology, shell scripts. [ 2] This is a windows-specific batch file. Depending on which platform you actually use, the batch file may look different. start rmiregistry start java com.ora.rmibook.chapter9.applications.ImplLauncher Bob 100 0 Alex 12 23 That is, it starts the RMI registry running and then runs a piece of Java code that launches the server objects. The ImplLauncher application, shown in Exam ple 9- 1 , is only slightly more complicated. Example 9-1. ImplLauncher.java package com.ora.rmibook.chapter9.applications; import com.ora.rmibook.chapter9.; import com.ora.rmibook.chapter9.valueobjects.; import java.util.; import java.rmi.; public class ImplLauncher { public static void mainString[] args { Collection nameBalancePairs = getNameBalancePairsargs; Iterator i = nameBalancePairs.iterator ; whilei.hasNext { NameBalancePair nextNameBalancePair = NameBalancePair i.next ; launchServernextNameBalancePair; } } private static void launchServerNameBalancePair serverDescription { try { Account_Impl newAccount = new Account_ImplserverDescription.balance; Naming.rebindserverDescription.name, newAccount; System.out.printlnAccount + serverDescription.name + successfully launched.; } catchException e{} } private static Collection getNameBalancePairsString[] args { int i; ArrayList returnValue = new ArrayList ; for i=0; i args.length; i+=3 { NameBalancePair nextNameBalancePair = new NameBalancePair ; nextNameBalancePair.name = args[i]; Integer cents = new Integerargs[i+1]; nextNameBalancePair.balance = new Moneycents; returnValue.addnextNameBalancePair; } return returnValue; } private static class NameBalancePair { String name; Money balance; } } All this does is parse the command-line arguments, create instances of AccountImpl corresponding to them, and then register those instances with the RMI registry. So, after running our batch file, we have two instances of Account registered with the registry. One corresponds to Bob, who has exactly 100 in his account, and one corresponds to Alex, who has 12.23 in her account. Of course, this is an unrealistic piece of launch code. In a real bank, the customer account information wouldnt be stored as command-line arguments to a batch file. But, as a pedagogical device, its pretty nifty.

9.3 Build Test Applications