The costs of UnicastRemoteObject

Since the RMI runtime maintains hashtables of servers and stubs, you actually do need to override equals and hashCode if there is a chance that a server could be compared to a stub.

8.2.3.2 The costs of UnicastRemoteObject

There are really only three situations when you wouldnt extend UnicastRemoteObject . The first is, obviously, if you need your server to subclass another object. Java is a single-inheritance language for implementations. If you want a server class to inherit from a particular class, then your server class cannot also inherit from UnicastRemoteObject . One solution in such cases is to use what the CORBA specifications call ties. A tie is a class that implements a remote interface but delegates all the behavior to the real server. That is, the server you implement actually consists of two objects: The tie server This extends UnicastRemoteObject and implements the remote interface. The implementation, however, simply forwards all method calls to the real server. The real server This is a subclass of another class. However, it also implements the remote interface and receives method calls from the tie server. If the remote interface is large, however, this can be rather cumbersome. The second problem is that subclasses of UnicastRemoteObject immediately begin listening for remote method invocations. Suppose the subclass constructor is particularly time-consuming, as in the following code snippet: public class PrinterManager_Impl extends UnicastRemoteObject implements PrinterManager { public PrinterManager_Impl { super5150; The well-known port of the printer manager :- go out to the registry and find all the printers. establish links to each of them and get information on their queues so that users can simply query us to find out about a ll the printers } } As part of UnicastRemoteObject s constructor, the printer manager will immediately be available to remote method invocations. That is, it will listen for remote method invocations even before PrinterManager_Impl s constructor has finished. Usually, this is not a problem. In fact, most of the time, servers cant be found by clients until the server is registered with a naming service. Recall that our launch code for Account_Impl , which is fairly typical launch code, did this only after the constructor finished: Account_Impl newAccount = new Account_ImplserverDescription.balance; Naming.rebindserverDescription.name, newAccount; However, if youre not using a naming service and providing another way for clients to connect with the server, you may need to be careful when extending UnicastRemoteObject . Practically speaking, the only time you need to worry about this is if you use a well-known port to connect to a server. That is, instead of using UnicastRemoteObject s zero- argument constructor, you pass in a port number. This can be convenient because it enables a client to bypass a naming service. On the other hand, you need to be careful becaus e the client could attempt to connect after the server has been vended e.g., after UnicastRemoteObject s constructor returns, but before the constructor has completed. The third reason for not extending UnicastRemoteObject is that you might want to extend either Activatable or PortableRemoteObject . Activatable and PortableRemote - Object are classes provided by Javasoft that play a role similar to the one played by UnicastRemoteObject . That is, UnicastRemoteObject provides the standard mechanisms for exporting an ordinary server. Activatable provides the standard mechanisms for exporting servers that take advantage of the activation framework, and PortableRemoteObject provides the standard mechanisms for exporting servers that use RMIIIOP. Well cover the Activation Framework in Chapt er 17 and RMIIIOP in Chapt er 23 .

8.3 Generating Stubs and Skeletons