Java network programming books: A comparative review
Laurence sifts through another batch of Java books, trying to separate the nuggets from fool’s gold
Five Java network programming titles landed on my doorstep for this review:
-
Java Network Programming, by Elliotte Rusty Harold (O’Reilly)
-
Java Network Programming, by Merlin and Conrad Hughes, Michael Shoffner, and Maria Winslow (Manning, an imprint of Prentice-Hall)
-
Advanced Java Networking, by Prashant Sridharan (Prentice-Hall)
-
Java Networking and Communications, by Todd Courtois (Prentice-Hall)
- Java Networking and AWT API SuperBible, by Nataraj Nagaratnam, Brian Maso, and Arvind Srinivasan (Waite)
Before I review the books in detail, let’s quickly look at each book’s main attributes:
Table 1: Java network programming books overview |
---|
Java Network Programming (O’Reilly) | Java Network Programming (Manning) | Advanced Java Networking | Java Networking and Communications | Java Networking and AWT API SuperBible |
---|
Price | 4.95 | 4.95 | 9.95 | 9.95 | 9.99 |
Pages, Chapters (Appendices) | 422, 15 (0) | 519, 29 (4) | 366, 12 (2) | 317, 8 (1) | 930, 13 (6) |
Index | Very Good | Poor | Very Poor | Poor | Very Good |
Glossary | No | No | Very Poor | No | Good |
CD-ROM | No (but source on FTP site) | Yes | Yes | Yes | Yes |
Authors | 1 | 4 | 1 | 1 | 3 |
Object- Orientation |
Average | Very Good | Average | Average | Average |
TCP/IP | Average | Poor | Poor | Poor | Poor |
Multithreading | Poor | Very Good | Average | Average | Good |
Streams | Poor | Very Good | Average | Average | Poor |
Serialization | Average | Average | Poor | Very Poor | None |
RMI | Very Good | Average | Very Good | None | None |
Servlets | Good | None | Good | None | None |
The last few attributes require some explanation:
The Object-Orientation attribute indicates to what extent the author(s) of the respective book used Java the way it is meant to be used: in an object-oriented way. Good Java books, whatever their focus, enforce good object-oriented practices. Inferior books use Java as if it were C or Pascal; that is, in a procedural way. Networking applications are very good candidate applications that benefit from being designed and implemented using object-orientation, so a good Java network programming book requires a strong emphasis on object-oriented analysis, design, and programming (OOA, OOD, and OOP).
The TCP/IP attribute indicates to what extent the book gives you a thorough TCP/IP primer. Personally, I would expect such a primer in any Java networking book; yet none of the books in this review dwell much on the internals of TCP/IP. But don’t let this particular oversight worry you; the whole point of Internet programming using Java is that the API lifts you to such heights of abstraction that much of the IP, UDP, and TCP protocol details disappear. If you’re like me, and you still want to know how the Internet works “under the hood,” then you should invest in the classic (and excellent) TCP/IP bible TCP/IP Illustrated, Volume 1 – The Protocols by W. Richard Stevens (Addison-Wesley).
The Multithreading attribute indicates to what extent the book uses and/or explains multithreading. Multithreading is a key ingredient in any non-trivial networking applications (especially for server-side programs).
The Streams attribute indicates to what extent the book uses and/or explains Java’s java.io classes. Making heavy use of stream classes in networking applications can simplify a design and make it more flexible.
The Serialization attribute indicates to what extent the book covers the 1.1 Serialization API and its uses. Pre 1.1 books do not touch on this API at all.
The RMI attribute indicates to what extent the book covers the 1.1 Remote Method Invocation API and its uses. Pre 1.1 books do not discuss RMI at all.
Finally, the Servlets attribute indicates to what extent the book covers servlets (server applets). Pre 1.1 books do not cover servlets at all.
Java Network Programming (O’Reilly)
Java Network Programming
treats the core java.net, java.rmi, and javax.servlet packages (Java’s packages that contain the APIs most relevant to network programming) in a thorough and logical manner. Chapter 1 sets out to entice the reader by enumerating some classic, state-of-the-art networking applications (chat, collaborative, and shopping cart applications, for example) for which Java can be easily used.
Chapters 2 and 3 introduce the basic TCP/IP and WWW concepts and mechanisms. The remaining 13 chapters use the various Java networking APIs as a guiding thread. Most of these chapters discuss a few classes at a time, consistently discussing constructors, methods, and exceptions, in that order. These chapters then end with a helpful section called “Some Useful Programs.” Within this section, you’ll find such programs as Javalookup, which performs DNS lookups from the command line; Pagesaver, which grabs a single Web page and saves it to your local hard disk while transforming all relative URLs to absolute URLs; and ImageSizer, which grabs a single Web page containing images and saves it while regenerating the image tags to contain width and height information. (Pages that omit this information do not allow the browser to display the page before all images are loaded, so ImageSizer magically fixes this annoying problem.)
The order of the chapters is logical, commencing with a discussion of the InetAddress
, URL
, Socket
, ServerSocket
, DatagramPacket
, and DatagramSocket
classes. The more advanced material continues with a discussion of the URLConnection
class and the non-trivial URL protocol and content handlers system, MulticastSocket
, RMI, and the Java Server API. The API material provided in each chapter is enhanced by adding extra layers of abstraction. For example, Chapter 9, which deals with UDP programming, presents a class (UDPClient
) that hides the low-level details of byte arrays normally required for UDP-level programming.
Despite the overall quality of the book, there are still several problems that manage to harm it. At a global level, Harold almost totally ignores multithreaded programming. This is very surprising since few non-trivial networking applications can be written in a single-threaded fashion. The book is also very sparse on figures and diagrams. The quality of code identifiers also leaves much to be desired; many of them are just one or two characters in length (a, e, o, u, s, r, p1, p2), or ignore established case conventions (uppercase variables, lowercase constants, lowercase class names). Using just two spaces as indentation unit, deeply nesting try-catch statements, and catching Exception
instead of more specific exception types further erodes code quality in this otherwise above-average book.
Java Network Programming (Manning)
This
Java Network Programming
is very different from its identically named competitor. This book devotes a lot of chapters to cryptographic theory and implementation, and the bulk of the material bypasses much of the microscopic detail of Java’s networking classes to build interesting and well-designed networking application frameworks on top of them. In addition, the book spends a surprisingly large number of chapters discussing Java’s I/O stream classes (as a prerequisite for designing the frameworks later on). The debatably large amount of pages used to study the stream classes is more than offset by the very high quality of Part III, “Real Networking Applications,” where stream classes form the architectural heart of a framework for client/server and virtual peer-to-peer applications.
Following Chapter 1, “Introduction to Networking,” the authors clearly show that they consider secure communications a very important topic: Chapters 2 and 3 are called “Introduction to Cryptography” and “The Java Security Model,” respectively. And it doesn’t end there. Five more chapters (for a total of 7 out of 29) are devoted to increasingly advanced cryptography, encryption protocols, and algorithms. Personally, I disagree that secure communications need to be covered in such detail. Although an important topic in its own right, it should be covered in just one or two chapters in a book with “Network Programming” as its title (admittedly the front cover does state “Covers Cryptographic techniques for secure Internet applications,” so readers are forewarned).
The book’s main strength is its very high-level approach to designing networking applications. The following quotation is just one small example of which wavelength these authors are on: “…the MessageCopier
will be the only thread that can experience an IOException
as a result of a failure in the underlying communications channel. We can thus write an application that does not need to be able to handle communications failures occurring wherever a read()
call occurs. Instead, we can write most of the code to only handle errors of incorrect message formats and other programmer errors….” This is software engineering in action, not Java hacking, and is why I really liked this book. Many authors can show you how to hack a bit of code, but few can show you how to design clean and flexible systems.
Another aspect of the book that impressed me was the quality and consistency of the diagrams. To explain the architecture of their stream-based networking applications, the authors do not use a conventional notation (like a Booch object diagram or such), but rather their own, infinitely clearer (!), iconography. Some of the later diagrams start to look so much like electronic circuit diagrams that they are almost small pieces of art. I loved them.
The book is not without its share of errors, though. One of the more serious errors is found in Chapter 27, “Object Serialization and Persistence.” Twice the authors state that ObjectOutputStream
inherits from DataOutputStream
. These statements are incorrect since ObjectOutputStream
inherits from OutputStream
and implements the ObjectOutput
interface. ObjectOutput
then implements the DataOutput
interface. The problem with this error (which at first doesn’t look very important) is that the authors further state that ObjectOutputStream.writeInt()
is inherited from DataOutputStream.writeInt()
, implying that ObjectOutputStream
streams are somehow compatible with DataOutputStream
streams, which is again false. The streams produced by ObjectOutputStream
and DataOutputStream
are totally incompatible, which is why JavaSoft couldn’t subclass DataOutputStream
to produce ObjectOutputStream
in the first place!
On the code front, as with the O’Reilly book, the authors use extremely poor program identifiers, including i1, o0, mI, qO (these would undoubtedly be qualified as “horrors” in Steve McConnell’s Code Complete, the bible of good coding practice (published by Microsoft Press)). In this case, the choice of identifiers seriously degrades the readability of the programs, even more so than in the case of the O’Reilly book. Surprisingly, in view of the otherwise excellent use of diagrams, the authors also forgot or did not deem it necessary to include class hierarchy diagrams for either Java’s networking packages or their own. In the case of Java’s networking packages, this omission becomes a problem because the authors also do not provide complete class listings. This means that the reader is left in the dark as to the full extent of the classes and methods available to the programmer.
Advanced Java Networking
If you read September’s game programming books review, you’ll remember that I am always suspicious of books containing the word “Advanced” in their title. Regrettably,
Advanced Java Networking
arrived this month to confirm my suspicions. The first chapter called “Basic Java” talks about the absolute basics to such an extent that you just know the remainder of the book will not deliver on the promise of its title. This is a shame because the table of contents sounds exciting due to the spectrum of subjects covered: Sockets, IDL, RMI, JDBC, the Java Web Server, and JMAPI, among others. Unfortunately, all of this material is presented in a very disappointing manner. The explanations are often sloppy (or just plain wrong), the author’s writing style is sloppy, the program listings are sloppy, and the diagrams are…you guessed it, sloppy.
Let’s begin with the sloppy explanations. Here are a few entries from the glossary:
- “Encapsulation: Object-oriented programming, practice of.”
- “Language Mapping: The means necessary to take one language and convert its syntax and semantics to another language.”
- “Serialization: The act of transforming a Java object into a string representation.”
- “Thread: A series of executable steps that are executed along with other steps.”
- “UDP: Unreliable Datagram Protocol.”
Any Java programmer with some experience will instantly recognize the flaws in the above “definitions.” Within the text, the author further mixes up the following concept pairs: byte and character, class and object, and subclassing and implementing an interface.
As for some examples of the poor writing style, how about this: “Once we detect some semblance of information coming across the socket, we must pop a thread automatically and let the thread get and process the information.” Need another example? Try this: “UDP is a ‘spit in the wind’ protocol. One day, you wake up, spit into the wind, and hope it will land somewhere.” Or this: “Datagrams are sort of like that old ‘I love Lucy’ episode in which Lucy and Ethel go to work in a candy factory. As they stand in front of a conveyor belt, little candies begin to flow out. Lucy and Ethel are able to wrap and package the candies as they come out. Soon, their boss speeds up the belt and the candies begin to flow out really fast and Lucy and Ethel are unable to keep up.” …. Did I say the title contained “Advanced?” Add to this a chapter on JavaBeans and one on JavaOS and JavaSoft’s Java Microprocessors, which have absolutely no place in a book on Java Network Programming.
Java Networking and Communications
Java Networking and Communications
is the smallest book in this line-up, consisting of a mere eight chapters, one of which contains material usually reserved for the book introduction (“What This Book Covers,” “What You Need To Know Already,” “What You Will Learn,” and “Acknowledgments”). Strike one!
Chapter 2, “Streams of Fury,” concentrates on Java’s stream I/O classes and lays the groundwork for the disappointing quality of what follows. When listing method summaries, for example, only the method name and a description of the method’s functionality is given. Full method signatures, showing argument and return value types, are rarely presented. The author prefers to write vague and useless statements like “This method, which comes in three different flavors….”
Weighing words carefully and using the correct terminology to produce an accurate text also didn’t seem to pre-occupy the author much. Constructors are called methods and way too many concepts are labeled as “interfaces.” In a Java context, it behooves the speaker to use the word “interface” with care, since it stands for one of Java’s key language features.
Several explanations in the text are completely incorrect. Here’s how the mark/reset mechanism for input streams is explained: “The way marking works is that a client can set a marker at a certain point on the input stream by calling mark(index)
.” The paragraph goes on to say that mark()
simply drops a marker in the stream. This is, of course, false. Had the author copied the formal parameter name used by the online Java docs for InputStream.mark()
, he would have written mark(int readlimit)
, which shows that the mark/reset mechanism works very differently from how the author explains it (I refer you to the online docs for the true explanation, in case you don’t already know it). Strike two!
Unacceptable errors occur more than once: Chapter 3, “Making the URL Connection,” states that “typically, a content handler is subclassed from something like java.awt.Frame
, and can be displayed to the user.” This is, I am sad to say, utter rubbish. The important (and rather complex) java.net content and protocol handler mechanisms lurking behind URL.getContent()
are explained away as follows: “This method [getContent()
] is out of the scope of this book because it does too much for you. It receives all the content data for you, parses it, and creates a content handler object for displaying the given content.” Obviously the author likes his readership to reinvent wheels. Consult the O’Reilly book for its two excellent chapters on how content and protocol handlers work (and at the same time understand why no Java networking book should ever claim that this topic is “out of the scope of this book”).
More disinformation awaits you in Chapter 4, “Better Living Through Threads.” On the topic of preemptive multithreading, the author thinks that Java guarantees preemptive behavior: “The Java runtime will make sure that, even though the code inside the run method might consume a great deal of computing resources, other tasks are given their fair share of time.” This is wrong, and the author would know as much if he had taken the trouble of studying the Java language specification. In a list of advantages ascribed to the use of multithreading, the author further states that “you can potentially solve certain kinds of problems faster…using concurrent threads. Examples of such problems include raytracing, digital signal processing, and some scientific simulations.” False again!
These examples are all CPU-bound applications (that is, the CPU is the bottleneck), and no amount of multithreading will speed these up on single-processor hardware (on the contrary, multithreading can only slow these applications down due to the slight overhead of context switching). Only I/O-bound applications (a Web browser, for example) can be sped up by multithreading, which is why multithreading is a core requirement for most networking applications.
Finally, in Chapter 5, “Networking with Sockets,” the author states that “IP also includes the concept of a host port” and “thus, to completely specify where an IP packet should be sent, you need to specify not only the 32-bit IP address but also the 16-bit port number.” I do believe the author is living in an alternative reality — the IP protocol does not have the slightest concept of port numbers, only UDP and TCP have. Strike three (not to mention four, five, six, and seven!), you’re out!
Java Networking and AWT API SuperBible
Despite the fact that “Networking” takes up the full width of the front cover in this book’s title,
Java Networking and AWT API SuperBible
devotes only 2 of 13 chapters (130 of 930 pages) to networking. So it is no wonder that this book does not go into the level of detail of the other books here reviewed. Chapter 10, “Network and Sockets,” is the first chapter dealing with networking, and Chapter 11, “Handling URLs and Networking Exceptions,” is the last. This is a reference-style book, so every chapter is structured as follows:
- A short introduction to the chapter’s material
- A reference-style description of relevant classes and all their methods
- An end-of-chapter project
Each networking chapter provides just five pages (including art) of introduction. The reference section lists every method using the following template: class name, purpose, syntax, parameters, description, imports, returns, see also, and an example. Roughly one out of three methods has an actual code example (the others refer to other method entries). Some of these examples are code snippets, while others can be compiled and run. Unfortunately, the code quality is rather typical of most Java books — inconsistent use of identifier case, comment styles, and indentation. Nevertheless, these code examples in combination with the two end-of-chapter projects, should give you enough base material to learn how to use the heart of Java’s java.net networking API.
The first end-of-chapter project, “A Client/Server Rendezvous Applet,” demonstrates how to use InetAddress
, Socket
, and ServerSocket
. The server-side in this example is properly multithreaded, as any non-trivial server should be. The second project is little more than a test program to fully exercise the URL class. There are several places in this book where grammar deteriorates to such a poor state that it makes you wonder where the editors were when the book went through its editing stages. For example, “First create a Server class which should accept connection from clients,” or “It should be a subclass of Thread class in Java and should contain….”
Purchase these books from Computer Literacy |
---|
Java Network Programming, by Elliotte Rusty Harold (O’Reilly) – ISBN: 1565922271 Java Network Programming, by Merlin and Conrad Hughes, Michael Shoffner, and Maria Winslow (Manning, an imprint of Prentice-Hall) – ISBN: 0138412065 Advanced Java Networking, by Prashant Sridharan (Prentice-Hall) – ISBN: 0137491360 Java Networking and Communications, by Todd Courtois (Prentice-Hall) – ISBN: 0138504547 Java Networking and AWT API SuperBible, by Nataraj Nagaratnam, Brian Maso, and Arvind Srinivasan (Waite) – ISBN: 157169031X |
The bottom line
Of the five books reviewed this month, I can recommend only two: Manning’s and O’Reilly’s Java Network Programming. Both are strong, as a whole, yet very different. If you happen to be interested in cryptography (as a peripheral issue to network programming) and/or high-level application design ideas, then Manning’s book will be your obvious choice. If you are less concerned with these issues and instead need an excellent reference to Java’s various networking APIs, then O’Reilly’s book fits the bill. Waite’s book contains too little networking specific material to be considered value for money at an expensive 9.99. And due to the extremely poor production values employed in the creation of both Prentice-Hall books, Advanced Java Networking and Java Networking and Communications, they are better left on the bookshop shelves altogether.