Java Reference
In-Depth Information
44. appointments.add(appointment);
45. }
46. else {
47. ArrayList appointments = new ArrayList();
48. appointments.add(appointment);
49. appointmentCalendar.put(appointmentKey, appointments);
50. }
51. }
52. }
The
CalendarImpl
object must use the RMI support class
UnicastRemoteObject
so that it can handle incoming
communication requests. In this case, the
CalendarImpl
constructor exports itself using the static method
UnicastRemoteObject.exportObject
.
CalendarImpl
also needs to have some way of publishing itself to the outside world. In RMI, the naming service
is called the
rmiregistry
. It must be running before the
CalendarImpl
object is created. The
rmiregistry
is
like a telephone book, providing a connection between a name and an object. When the
CalendarImpl
object
registers itself with the
rmiregistry
through the
rebind
method it binds the name "calendarimpl" to the stub of
this remote object.
For a client to use the remote object it has to do a lookup in the
rmiregistry
of the host machine and receive the
stub to the remote object. You can compare the stub to a telephone number. You can use that number from
anywhere, on any phone, and you get connected to someone answering the number you're calling. In this example,
the
CalendarHOPP
class acts as the client for the
CalendarImpl
object.
Example A.183
CalendarHOPP.java
1. import java.rmi.Naming;
2. import java.rmi.RemoteException;
3. import java.util.Date;
4. import java.util.ArrayList;
5. public class CalendarHOPP implements Calendar, java.io.Serializable{
6. private static final String PROTOCOL = "rmi://";
7. private static final String REMOTE_SERVICE = "/calendarimpl";
8. private static final String HOPP_SERVICE = "calendar";
9. private static final String DEFAULT_HOST = "localhost";
10. private Calendar calendar;
11. private String host;
12.
13. public CalendarHOPP(){
14. this(DEFAULT_HOST);
15. }
16. public CalendarHOPP(String host){
17. try {
18. this.host = host;
19. String url = PROTOCOL + host + REMOTE_SERVICE;
20. calendar = (Calendar)Naming.lookup(url);
21. Naming.rebind(HOPP_SERVICE, this);
22. }
23. catch (Exception exc){
24. System.err.println("Error using RMI to look up the CalendarImpl or register the
CalendarHOPP " + exc);
25. }
26. }
27.
28. public String getHost(){ return host; }
29. public ArrayList getAppointments(Date date) throws RemoteException{ return
calendar.getAppointments(date); }
30.
31. public void addAppointment(Appointment appointment, Date date) throws RemoteException
{ calendar.addAppointment(appointment, date); }
32. }
The
CalendarHOPP
provides a key benefit over a conventional RMI client - it can locally run what would
normally be remote methods. This can provide a substantial benefit in terms of communication overhead. The
HOPP implements the same remote interface, but it will not export itself. It keeps a reference to the stub and
forwards all the method calls to the stub that it does not (or cannot) handle. Now it can implement the methods
that it wants to execute locally—in this example, the
getHost
method. The HOPP can be registered with the
rmiregistry
like a normal stub, but it now has the ability to execute methods locally.
Support classes for this example provide the ability to create
Appointment
objects to be stored by
CalendarImpl
.