Modifying Ordinary Servers Incorporating a Custom Socket into an Application

RMIs default socket factory. The first option, modifying individual server classes, gives us a very fine-grained level of control in which each server can use a different custom socket class. Setting RMIs default socket factory is a much coarser way to do things. Changing the default socket factory means that any servers that dont set their own socket factories will use the new default types.

18.2.1 Modifying Ordinary Servers

UnicastRemoteObject has three constructors: protected UnicastRemoteObject protected UnicastRemoteObjectint port protected UnicastRemoteObjectint port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf Until this point, weve used only the first two of these in our servers. In fact, weve mostly used the first one, as in the following code snippet: public class Account_Impl extends UnicastRemoteObject implements Account { private Money _balance; public Account_ImplMoney startingBalance th rows RemoteException { _balance = startingBalance; } ... } This is a perfectly reasonable thing to do; the zero-argument constructor gives the RMI runtime the ability to reuse an existing server socket, whereas the one-argument constructor forces the RMI runtime to create a server socket that listens on the specified port. However, in order to use custom socket factories, we need to use the third constructor. Consequently, the code change consists of modifying the previous code snippet to use the third constructor: public class Account_Impl extends UnicastRemoteObject implements Account { private Money _balance; public Account_ImplMoney startingBalance throws RemoteException { super0, new PropertyBasedMonitoringSocket_RMIClientSocketFactory , new PropertyBasedMonitoringSocket_RMIServerSocketFactory ; _balance = startingBalance; } ... } We still pass 0 in as the first argument. Using 0 as the value of port means that RMI is free to choose the port for the server socket, which in turn means that RMI is free to reuse an existing server socket, using the mapping described earlier. Ordinary servers that arent subclasses of UnicastRemoteObject are handled similarly. Recall that stubs for these types of servers are created using one of UnicastRemote - Object s static export methods: static RemoteStub exportObjectRemote obj static Remote exportObjectRemote obj, int port static Remote exportObjectRemote obj, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf These methods are called from within the launch code, as in the following snippet from Chapt er 9 : private static void launchServerNameBalancePair serverDescription { try { Account_Impl2 newAccount = new Account_Impl2serverDescription.balance; RemoteStub stub = UnicastRemoteObject.exportObjectnewAccount; Naming.rebindserverDescription.name, stub; System.out.printlnAccount + serverDescription.name + successfully launched.; } catchException e{} } The change to the launch code is exactly parallel to our changes of the subclasses of UnicastRemoteObject . Instead of calling the one-argument version of export , we call the four-argument version. The preceding code becomes the following: private static void launchServerNameBalancePair serverDescription { try { Account_Impl2 newAccount = new Account_Impl2serverDescription.balance; RemoteStub stub = UnicastRemoteObject.exportObjectnewAccount, 0, new PropertyBasedMonitoringSocket_RMIClientSocketFactory , new PropertyBasedMonitoringSocket_RMIServerSocketFactory ; Naming.rebindserverDescription.name, stub; System.out.printlnAccount + serverDescription.name + successfully launched.; } catchException e{} }

18.2.2 Modifying Activatable Servers