RMI books hit the shelves
Learn RMI with a book that suits your programming needs
Until recently, if you wanted up-to-date information about Java’s Remote Method Invocation (RMI), you had to piece together information from magazines, tutorials, and mailing lists. A few Java books provided a chapter or two devoted to RMI, but those were only intended as introductions. After a long dry spell, two new books devoted to RMI were published this year. In this article, I’ll review both of them:
- Mastering RMI: Developing Enterprise Applications in Java and EJB, Rickard Öberg (John Wiley & Sons)
- Java.rmi: The Remote Method Invocation Guide, Esmond Pitt and Kathleen McNiff (Addison-Wesley)
The table below provides a quick review of the books’ main characteristics. The first three rows are the administrative details. The remaining rows rate each book’s coverage of different RMI topics.
RMI books overview | ||||||
---|---|---|---|---|---|---|
Title | Mastering RMI | Java.rmi | ||||
Price | 9.99 | 9.99 | ||||
Total pages | 305 | 284 | ||||
CD-ROM/Companion Website | Yes / Yes | No / Yes | ||||
Basic RMI | Good | Good | ||||
Serialization | Good | Excellent | ||||
Naming services | Good | Average | ||||
Threading issues | Excellent | Good | ||||
Exceptions | Average | Excellent | ||||
Dynamic classloading | Excellent | Excellent | ||||
Sockets | Good | Good | ||||
Activation | Average | Average | ||||
RMI over IIOP | None | Excellent | ||||
Jini | Excellent | None | ||||
Security | Average | Good | ||||
Firewalls | None | Excellent | ||||
Agents | Good | Average | ||||
Basic EJB | Good | None | ||||
Scale: None, Poor, Average, Good, Excellent |
Mastering RMI: Developing Enterprise Applications in Java and EJB
Rickard Öberg’s Mastering RMI emphasizes instruction by example with a collection of tutorials that show and explain extensive sample code. If you are new to RMI, the ample code is a big plus because you can experiment with meaningful applications. The downside to the book’s tutorial approach is that coverage of some topics spreads across more than one chapter.
Chapter 1 is an overview of client/server architectures. It provides introductory information on distributed computing and network protocols. Chapter 2 introduces RMI and then goes into its details. Öberg discusses the difference between the RMI specification and Sun’s default implementation, which is based on the Java Remote Method Protocol (JRMP). He also introduces the threading model, marshalling, naming, and dynamic classloading, and then uses these concepts in Chapter 3 to describe a simple example application.
Chapter 4 improves that example application by using the Java Naming and Directory Interface (JNDI) and dynamic classloading. One of the book’s strengths is that Öberg provides several examples on dynamic classloading, which is often difficult to configure in RMI. The chapter covers several dynamic classloading pitfalls in depth.
Chapters 5 and 6 contain topics optional for many RMI users. Chapter 5 describes custom socket factories while Chapter 6 covers activation. Unlike the first four chapters, I didn’t feel I had mastered these subjects after reading their respective chapters. The sample code is well described, but I was left wondering which methods am I required to override when creating a custom socket factory? The information on activation likewise left me with the need to do further study before writing code that uses this RMI capability.
Chapter 7 is one of the book’s best chapters. It provides the source code and a detailed description for a chat application. Öberg explains the tradeoffs involved when choosing from different performance-improving techniques. He discusses pushing versus polling and balancing message throughput with latency. On the server side, the chosen implementation uses multiple threads to service multiple queues. On the client side, Öberg uses SwingUtilities.invokeLater()
to speed the client’s return when the server pushes a message to it. If you want to implement an RMI application that scales up to handle multiple users, this chapter is almost worth the book’s price alone.
Chapter 8 uses a different real world application: a mobile agent system. The example code uses RMI to pass an agent to several different programs. Öberg thoroughly explains a Java object’s ability to switch back and forth between being used remotely or only locally. Finally, Öberg describes additional dynamic classloading pitfalls.
Chapter 9 is a well-done introduction to Jini, Sun’s technology for delivering services across a network. Jini is built on top of RMI and provides powerful capabilities that can improve an RMI application’s robustness and flexibility. Öberg describes Jini’s five main building blocks: discovery, lookup, leasing, remote events, and transactions. Öberg modifies Chapter 3’s example application to show how to add Jini to an RMI application. Be aware, though, that this chapter only introduces you to Jini; Öberg provides pointers to additional sources if you want to learn Jini in-depth.
Chapter 10 ends the book with a discussion of RMI and Enterprise JavaBeans (EJB). Like Jini, EJB is built on top of RMI. Öberg describes the roles of EJB containers and components, and the four EJB component types: stateless session beans, stateful session beans, entity beans, and message-driven beans. This time, he modifies Chapter 3’s example application to show EJB in action. The book’s subtitle not withstanding, this chapter is intended only as an EJB introduction.
The only serious disappointment for me was that an important topic — using RMI over the Internet Inter-Orb Protocol (IIOP) — was ignored, mainly because Öberg focuses on standard RMI; he only mentions IIOP briefly in Chapters 1 and 10. One final note: the sample programs I tried from the CD-ROM all compiled and ran fine using JDK 1.3.
Java.rmi: The Remote Method Invocation Guide
Pitt and McNiff’s Java.rmi uses a textbook style to describe RMI. It includes exercises in 14 of the 18 chapters, and the material is arranged by topic. The example programs tend to be skeletal, providing just enough source code to illustrate a single concept. The authors provide valuable pointers to outside references throughout the text. They even provide tips on how to search for relevant messages in Sun’s RMI-Users mailing list archive.
Chapter 1 provides a minimal RMI introduction and overview, with a small sample program that demonstrates how to modify a regular program to use RMI. It struck me as odd that the authors did not explain how to run the sample program. Chapter 2 briefly explains the difference in semantics between local and remote method calls. It contains a good explanation of an important topic: how RMI handles arguments and return values. Chapter 3 looks in-depth at Java serialization, starting with an overview and then describing the low-level details. This is one of the best chapters in the book — performance tips are included.
Chapter 4 briefly discusses how to define a remote interface. It explains which RMI rules are enforced by the compiler and which are enforced by the runtime. Chapter 5 introduces you to writing client-side RMI code and points out important design challenges: remote failure, partial failure, and network latency. Complete techniques for handling these challenges are not provided — they are beyond the book’s scope. Chapter 6 does an adequate job of describing the RMI registry utility. Pitt and McNiff mention you can start your own registry in your program, but I was disappointed that they didn’t provide any sample code.
Chapter 7 explains how to write a standard RMI server: implementation of the remote interface methods, threading issues, sockets, ports, and the Unreferenced
interface. The explanation of the different techniques for creating a remote object — via inheritance or explicit export — is well done, as is the Unreferenced
interface discussion. Chapter 8 provides detailed information on RMI and the Java Security Model, describing policy files and required permissions. Chapter 9 rounds out the coverage of basic RMI topics by providing a good description of dynamic classloading: what it is, how it works, and how to avoid its pitfalls.
Chapter 10 delves into activation. Pitt and McNiff provide a step-by-step guide on writing activation code, along with specific recommendations on which exceptions to catch on the client side. They also discuss in detail how activation works “under the covers.” Chapter 11 is a short chapter on socket factories, and explains why you might use one with a skeletal example. Chapter 12 covers common design patterns you can use to develop RMI applications: Adapter, Proxy, Singleton, and so on. The authors point out RMI limitations that can affect the implementation of certain patterns.
Despite its JNDI and Jini-focused title, Chapter 13’s coverage of JNDI is adequate, but the space devoted to Jini is less than a full page, and does not even provide skeletal sample code. Chapter 14 is a well-done explanation of RMI over IIOP; the authors point out the subtle restrictions and differences in an IIOP environment, and how best to deal with them. Skeletal example code demonstrates how to support both JRMP and IIOP in a single RMI server.
Chapter 15 starts off the book’s final section with an excellent description of using RMI through firewalls. Pitt and McNiff describe in detail which configurations will and will not work. Chapter 16 lists conversational security issues for distributed applications: identity, privacy, and integrity. The authors then describe how Sun’s proposed RMI Security Extension would address those issues. Chapter 17 is nonessential; entitled “Beyond Unicast,” it describes RMI servers based on datagrams instead of streams and proposes RMI enhancements to enable support of multicast servers. Chapter 18 is a grab bag of miscellaneous topics. The most interesting of these is a decent performance-tuning discussion.
Java.rmi contains two appendices and a pamphlet. Appendix A is an excellent description of all RMI exceptions. Pitt and McNiff not only describe the exceptions but also offer tips on what might cause each exception at runtime, along with suggestions on how to handle the exception in your code. For someone attempting to develop a sophisticated application using RMI, this information alone might be worth the book’s price. Appendix B lists the generic RMI system properties and those that are specific to Sun’s RMI implementation. The pamphlet is an RMI Almanac that lists all RMI classes, interfaces, and exceptions. Personally I prefer to use the Javadocs for this sort of information.
The lack of meaty example code is occasionally frustrating, but the “just the facts” approach makes it easy to find information on a specific topic. In addition, the authors provide informed opinions on the best way to deal with several design and implementation challenges. I picked up a few tips and will no doubt refer to this book in the future when researching RMI issues.
Which book should you buy?
Both books are well written, so consider the topics that are important to you. Mastering RMI has information on Jini and EJB that you won’t find in Java.rmi. Conversely, Java.rmi has information on firewalls and RMI over IIOP that Mastering RMI excludes. Even more important though than the difference in covered topics is the difference in writing styles. If you prefer a tutorial approach with extensive example code, buy Mastering RMI. If you prefer more of a textbook approach, Java.rmi is the book for you.