Java RMI By William Grosso The unconfirmed error reports are from readers. They have not yet been approved or disproved by the author or editor and represent solely the opinion of the reader. Here's a key to the markup: [page-number]: serious technical mistake {page-number}: minor technical mistake : important language/formatting problem (page-number): language change or minor formatting problem ?page-number?: reader question or request for clarification This page was updated June 20, 2008. UNCONFIRMED errors and comments from readers: [10] First line of code in Example 1-1; public class ViewfileFrame should be public class ViewFileFrame (13) 4th paragraph; January 2002: First Edition 1) Perhaps the line... This is because of memory-based stream classes such as: ByteArrayInputStream. Should be... This is because of memory-based stream classes such as ByteArrayInputStream. 2) In the code snippit testParsing() The line... ByteArrayInputStream testStream = new ByteArrayInputStream(testString getBytes()); Should be... ByteArrayInputStream testStream = new ByteArrayInputStream(testString. getBytes()); (note the "period" operator in testString) [13] In the code snippet testParsing(); String testString = "A string whose parse results are easily checked for" + "correctness." should be String testString = "A string whose parse results are easily checked for" + "correctness."; {67} bottom of page; "com.ora.rmi.book.chapter4..Printer" should be "com.ora.rmi.book.chapter4.Printer" (68) Typos; 1) "$param DocumentDescription_1" should be "$param_DocumentDescription_1". 2) "om.ora.rmibook.chapter4.PrinterException" should be "com.ora.rmibook.chapter4.PrinterException" {69} code block; single quote (') before java.io.ObjectInput should be removed. {69} code block; Where is the final close bracket (brace) after 'return $result;' ? (70) Incorrect ellipsis representation; In a few places in the book, four periods are used for an ellipsis. An ellipsis should be a three dot symbol. [82] chapter 4; Perhaps I overlooked something, but I had serious problems getting the example from chapter4 running. I found out at last, that I had to provide a java.policy file and how to grant the right permissions. But I didn't know about a java.policy file before. So I found it a little difficult to resolve my problems. Maybe you should mention this file somewhere of provide a sufficient one in the zip-file with the examples. (104) Second Paragraph; "...make sure that clients are invoke only transactions..." should read "...make sure that clients are invoking only transcations..." [130] java coding for class Money; If the _cents variable changes its value ( via the add() or subtract() methods ), then the _hashCode and _stringifiedRepresentation variables in the superclass ValueObject have to be changed to reflect the new value of _cents. Calling toString() on a Money object invokes the toString() in the superclass ValueObject part, so if _cents changes the wrong value gets returned. (165) middle of page -- second hilite still has writeObject(serializableObject); In the second hilite the author is showing how to manually serialize the object so it should NOT have the writeObject. {178} first line; Usage of the method `copy' is inconsistent with the declaration of `copy' a few lines below. `copy' needs three parameters, not two... {194} missing declaration of "_stringifiedRepresentation". This variable is used in the "readExternal" function {207} Definition of "threadsafe" and "multithreaded code" are reversed. Defintion of threadsafe code should be "code that necessarily has several threads running through it and still executes correctly". [266] code for returnObject; Page 264 implies that the PoolHelper does not need to be threadsafe. While this is true for SimplePool, the changes introduced by ThreadedPool1 force the PoolHelper to manage its own threadsafety. In particular, returnObject and createAndAddObject both make calls into the _helper from an unsynchronized context. Thus if two threads call returnObject simultaneously, the helper will have simultaneous threads [266] code for createAndAddObject; The second if-clause will never execute, since createdObject is inititalized to null and never assigned another value. [266] entire ThreadedPool1 example; The theadsafety of the ThreadedPool examples is very unclear, and should be explained more throroughly. If returnObject is given an invalid object, no notification occurs (to threads that are waiting for objects to be created). createAndAddObject only notifies if an object is actually created, which will never happen once the max # objects is reached. (Actually this is an assumed reading of the obviously-buggy code.) So, assume the maximum number of objects is created and all are given out. A new call to getObject comes in: - getLocallyAvailableObject returns null - creator.askForObject is invoked, and then the getObject thread waits. - The creator's run() loop will awaken, and call createAndAddObject, which does nothing since the max count has been reached. The creator then waitss for another call to askForObject. At this point both threads are stalled. The getObject thread will wait until another thread calls returnObject with a VALID object. But what if (a) all the returned object happen to be invalid AND (b) no other thread calls getObject? The original call will wait forever, since nothing will ever notify EITHER the getObject thread or the creator thread. It seems to me that returnObject should ALWAYS notify, so that, even if the returned object is invalid, the threads stalled at waitForAvailableObject (via getObject) will have a chance to askForObject again to have a replacement created. (267) Halfway; ThreadedPool1 misspelled as ThreadedPoo11 [267] code for ObjectCreator.run(); The control structures here are unclear. The innermost WHILE loop will only terminate when _requestPending is true, which means that needToCreate will always be true when the synchronized block exits. This makes the next IF unnecessary. Is there a scenario under which needToCreate will be false? (268) 3rd paragraph; The verb tenses used in the third paragraph seem to be inconsistent. The second and third sentences are in the past tense, despite the fact that they are referring to code that has not yet been displayed. The paragraph is describing a few changes that are referred to in the previous paragraph using the _future_ tense, so referring to them in the past tense sounds wrong, like they're referring to the previous code example. Present tense would work better--changing "rewrote" to "rewrite" in the second sentence, and "added" to "add" in the third--because that's what the first and fourth sentence use. [271] createAndAddObject Method; This method contains an Object called createdObject and an Object called newObject. These objects must be the same. Otherwise, the null!=createdObject condition at the end of the method will never be true. [272] Top; The removeAnObject method needs to include a decrementor for _totalNumberOfObjects (_totalNumberOfObjects--), probably following the _helper.dispose(objectToRemote) call. Otherwise, the total number of objects never gets decremented after removing an object from the pool (from the PoolShrinker). {277} footnote; In the source code package I downloaded, there was not a package "com.ora.rmibook.chapter12.bank.scale", nor was there "bank.scale" in any other chapter's packages. [427] 2nd para (not the box); The author says.. The bootstrap classloader attempts to load classes from the file system using the CLASSPATH.. Nope The bootstrap just loads rt.jar, i18n.jar (perhaps some others?) but not the classpath. Another classloader is setup for the app (which has the bootstrap as parent) and this allows the sandbox for security permissions to take effect (1.2 on). The bootstrap has no security on it. Chapter 10: Comparing Externalizable to Serializable; ReallyEfficientMoney can't be deserialized. [Chapter 10] online version (about a third the way though - search for quoted material); The author says: "While arrays are first-class objects in Java, they aren't serializable objects." This is incorrect. Arrays *are* serializable in Java. consider: class ArraySer { java.io.Serializable ser = new Object[0]; //NP } Apart from this error, the chapter on Serialization was an interesting treatment of a topic with some very difficult and confusing details.