Jini in a Nutshell by Scott Oaks & Henry Wong 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. This page was updated June 15, 2001. 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 UNCONFIRMED errors and suggestions from readers: {24} This isn't an errata per se, but Java 1.3 changed the way in which certain things work, and we're getting a few questions about it. So... In 1.3, the command to start rmid has changed to rmid -J-Djava.security.policy=/files/jini1_0/java.policy.all {36} First paragraph of "Object Serialization" section. end of paragraph: text reads "...in all other areas of Java, objects are passed strictly by reference. Remote objects, on the other hand, are passed by reference..." Should this be "by value"? If not, then what does this mean? [48] Item 6: I had to run the "ComplexNumberClient" like this ("ravel" is the name of my local system): $ java -Djava.security.policy=/usr/local/jini1_0_1/java.policy.all Complex-NumberClient rmi://ravel:1099 i.e., I had to add the port ":1099" to the rmi://server tag (which you show as a correction added to the 5-00 printing.) Also your statement of the result: 8.0 + 5.0i is erroneous, you need to switch real <-> imaginary, as the code indicates and I find on actually running the example: 5.0 + 8.0i {48} Code under 1: server% javac CompexNumber.java.......... should read: server% javac ComplexNumber.java.......... {50} 3rd paragraph: In Example 3-3, it is written that the ConvertClient code from Example 3-1 (page 44) can be reused. This is not true, it only works if the following line is inserted (at the beginning of the main method): System.setSecurityManager(new RMISecurityManager()); {53} 2nd paragraph: "To mark a service object as inactive, call it's inactive() method" should read "To mark a service object as inactive, call the Activable.inactive(ActivationID) method [because it's a static method] and supply the id of the object". It's a major difference, because you don't need a reference to the object to do this. {53} 3rd paragraph: The text refers to the interface "java.rmi.activation.Unreferenced". It should read: "java.rmi.server.Unreferenced". (66) code that handles failed services: cl.errored(s); should read sf.errored(cs);. {66} First Half; The service Finder for example 4-1 do not work in the actual printed version. Because the service finder seems to wait BEFORE the lookup services are discovered. So I've make a few change to resolve this : - First I'va applied a limitation for the waiting on the getObject() method (in the ServiceFinderClass). public synchronized Object getObject() { while (returnObject.size()==0) { try{ wait(500); System.out.println("getObject(), Waiting..."); } catch (InterruptedException e) {} } return ((ServiceItem)returnObject.elementAt(0)).service; } -And I've modified a bit the ConvertClient.java file, so the main method instanciate a ConvertClient class, and this class wait for the discovery service. public class ConvertClient { public void ConvertClient () {} public void working_c() throws Exception { System.setSecurityManager(new RMISecurityManager()); ServiceFinder sf=new ServiceFinder(ConvertService.class); ConvertService cs; System.out.println(" Creation ConverService"); boolean done=false; while(!done) { try {wait(1000);} catch (Exception e) { System.out.println(" error : "+e);} cs=(ConvertService)sf.getObject(); try { System.out.println(cs.convert(18)); done=true;} catch (RemoteException e) { System.out.println(" Remote Error : "+e); sf.errored(cs);} } } public static void main(String args[]) throws Exception { ConvertClient cc=new ConvertClient(); cc.working_c(); } } [67] 4.2.4: Running the basic Example 4.1 just waits in the ServiceFinder's getObject()'s wait(). Not able to discover the Server. Any reason why? [67] top half (example): Two unrelated problems in running the example. Firstly, there is no indication that the the Discovery and Lookup service needs to be started. Second, step 5 reads: "Now we can run the client..." but the command runs the service instead of the client. [67] 4.2.4: I am having a similar problem with the ServiceFinder that others have noted. When using Sun's Service Browser from their JINI examples, I am able to discover lookup services via multicast, no problem. But the code furnished here never finds anything. I am on a win2k machine. {76} 1st paragraph: On my computer (win98), this example was not working. Apparently, the lookup method queries only known lookup services, so when called right away, it has not yet established contact to any, and the lookup method will block forever. A Thread.sleep(2000) directly before the "lookup(...)" call fixes this problem. (76) Sample Code: The ClientLookUpManager class cannot be found in net.jini.lookup; my guess is that Sun did not ship it with its final version of Jini 1.1. Would you have any additional information on what happened to this class? [182] in the first for loop (middle of the page): In the loop for (int i=0; i< current.length; i++) { I think that code included in the else bracket should be applied whatever the value of o is. In the if bracket, we do a register, which adds a new Lease in leases, but this Lease is never put in newLeases and will be lost. [190-1] Example 11-2; The book states that Example 11-2 is used in Example 11-1, but in fact those example files are totally different from 11-1 source code.