Modifying the launch code

• Remote iterators. Results are currently returned as either an instance of Remote or as ContextList . This might be a bad design for the reasons outlined in Chapt er 7 . All of these features are useful™there are naming services out there that support each one of these features. In addition, none of these are particularly hard to add to our naming service though a seat-of-the-pants estimate is that including them all would double the code size. Our naming service is just one possible design choice among many.

15.7 Switching Between Naming Services

Now that we have another naming service, its natural to wonder how much work it is to adapt our existing code to use it. The answer is that its pretty easy to switch between naming services. In order to adapt an application, we need to do three things: • Decide how were going to store information in the naming service • Rewrite the launch code to create the necessary contexts and store the stubs appropriately • Rewrite the clients lookup code to reflect the new naming structure There are two very important things you dont need to change: • The actual servers. Neither the interfaces nor the implementations need to change at all. • The distributed garbage collection strategy. Because leases are automatically maintained by RMI, binding stubs into this naming service will keep the associated servers alive, just as binding stubs into the RMI registry kept the associated servers alive.

15.7.1 Adapting the Bank Example

One way to adapt the bank example is to bind stubs into two different contexts, checking and savings . Stubs for checking accounts will be bound into checking and stubs for savings accounts will be bound into savings . Another way to accomplish this is to create an attribute called account_type and use two values checking and savings .

15.7.1.1 Modifying the launch code

In order to gratuitously demonstrate federation in action, we will actually launch each of our contexts in a separate JVM. To do this, we will use the AdditionalContextLauncher class. Heres the code for it: public class AdditionalContextLauncher { public static void mainString[] args { for int i = 0; i args.length; i++ { launchContextargs[0], args[i]; } } private static void launchContextString baseContextMachine, String pathPlusName { StringTokenizer tokenizer = new StringTokenizerpathPlusName, , false; int numberOfPathTokens = tokenizer.countTokens -1 ; Path path = null; if 0=numberOfPathTokens { String[] pathComponents = new String[numberOfPathTokens]; for int counter=0; counter numberOfPa thTokens; counter++ { pathComponents[counter] = tokenizer.nextToken ; } path = Path.buildPathpathComponents; } String name = tokenizer.nextToken ; try { ContextImpl newContext = new ContextImpl ; Context startingContext = BaseContextImpl getStubFromServerbaseContextMachine; startingContext.bindSubContextpath, name, newContext; } catch NamingException e { System.out.printlnFailed to launched context + pathPlusName; System.out.printlne.getDescription ; e.printStackTrace ; } catch Exception ee { ee.printStackTrace ; } } } This is a simple program that expects at least two, possibly more, arguments on the command line. The first argument is the machine where the base context is running, and the additional arguments are paths for the various contexts that should be added to the naming structure. Thus, the launchcheckingcontexts.bat batch file consists of the following single line: start java -cp d:\classes -Djava.security.policy=c:\java.policy com.ora.rmibook chapter15.basicapps.AdditionalContextLauncher 127.0.0.1 checking This isnt a particularly good way to bind subcontexts. Note that we dont use createsubContext at all in AdditionalContextLauncher . In fact, all messages between contexts added by AdditionalContextLauncher go through RMI through serialization and socket communication. Once weve written the code and the batch files that create the contexts we will need, we need to modify the code that binds our servers into the naming service. Here, for example is the code from the ImplLauncher class in the com.ora.rmibook.chapter15.bank.applications package that binds a server into the naming service: Account_Impl newAccount = new Account_ImplserverDescription.balance; Path path = Path.buildPathnew String[]{serverDescription.contextName}; if null==baseContext { getContext ; } baseContext.bindpath, serverDescription.name, new AttributeSet , newAccount; System.out.printlnAccount + serverDescription.name + successfully launched.; serverDescription is just an instance of a static inner class named AccountDescription : private static class AccountDescription { String name; Money balance; String contextName; } This compares quite favorably to the launch code that used the RMI registry™ ImplLauncher has four more lines of code but binds stubs to subcontexts.

15.7.1.2 Modifying the client code