Naming-Service Changes Using Dynamic Classloadingin an Application

return; } In the middle of this code, pList is created and filled with the values of system properties for the JVM that will be launched by the Activation Framework. If the application is going to use dynamic classloading, then pList must also contain an entry for the java.rmi.server.codebase property. The following code sets the value for java.rmi.server.codebase in pList to whatever the launching JVMs value for java.rmi.server.codebase is: private static void createActivationGroup throws ActivationException, RemoteException { ActivationGroupID oldID = ActivationGroup.currentGroupID ; Properties pList = new Properties ; pList.putjava.security.policy, d:\\java.policy; pList.putsun.rmi.transport.connectionTimeout, 30000; String codebase = System.getProperty ; if null=codebase 0=codebase.length { pList.putjava.rmi.server.codebase, codebase; } ActivationGroupDesc.CommandEnvironment configInfo = null; ActivationGroupDesc description = new ActivationGroupDescpList, configInfo; ActivationGroupID id = ActivationGroup.getSystem . registerGroupdescription; ActivationGroup.createGroupid, description, 0; return; } You probably noticed when we started the servers that we also amended our security policy. This was necessary in order to prevent security exceptions from being thrown when the client attempts to make a connection to the registry or the server. Well talk more about security policies in the next chapter. In the meantime and only for the meantime, just use the following for the security policy file: grant { permission java.security.AllPermission; };

19.5.2 Naming-Service Changes

In most application architectures, the launch code binds stubs into a naming service, and clients retrieve stubs from the naming service. This means that the naming service, which has an instance of the stub, will need all the associated class definitions. In the banking application, for example, we bind stubs that implement the Account interface into the RMI registry: public interface Account extends Remote { public Money getBalance throws RemoteException; public void makeDepositMoney amount throws RemoteException, NegativeAmountException; public void makeWithdrawalMoney amount throws RemoteException, OverdraftException, NegativeAmountException; } This means that the JVM containing the registry needs to load the following classes: Account AccountImpl_Stub Money NegativeAmountException OverdraftException The problem is this: if the registry had any of these classes on its local classpath, then it would load them from the filesystem instead of using the URLs contained in their annotation. However, if the naming service loads the class from the local filesystem, then, when the client requests the instance, the original annotation will be lost the classes will either not have an annotation or will be annotated with the value of java.rmi.server.codebase thats set for the naming services JVM. The only way we can guarantee to preserve codebase annotations is by paying attention to the third rule from earlier: If a class wasnt loaded from the filesystem but was instead loaded via dynamic classloading, the original annotation, which was used to load the class in the first place, is retained and sent as the class annotation. This means that no application-specific classes should be on the naming services classpath. Failing to clear the naming services classpath is probably the single most common reason why dynamic classloading breaks down. It can be really annoying because the calls to bind or rebind will succeed. The failure will only become apparent when the client tries to retrieve the stub.

19.5.3 Client-Side Changes