Examining the skeleton Implementing a Printer

After compiling the server, we need to generate stubs and skeletons. The stubs and skeleton classes are in the same package as the server class in this case, com.ora.rmibook.chapter4.printers . In this case, we simply use: rmic -keep -d d:\classes com.ora.rmibook.chapter4.printers.NullPrinter

4.3.2.1 Examining the skeleton

Just as we briefly examined the generated stub, its also worth looking for a moment at the skeleton thats generated. The generated skeleton has one major method, named dispatch . dispatch is the method that actually forwards requests to the server. Heres a snippet of code from the dispatch method of our skeleton: public void dispatchjava.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash throws java.lang.Exception { ... validation and error-checking code omitted com.ora.rmibook.chapter4.printers.NullPrinter server = com.ora.rmibook.chapter4.printers.NullPrinter obj; switch opnum { case 0: printDocumentDocumentDescription { com.ora.rmibook.chapter4.DocumentDescription param_DocumentDescription_1; try { java.io.ObjectInput in = call.getInputStream ; param_DocumentDescription_1 = com.ora.rmibook.chapter4.DocumentDescription in.readObject ; } catch java.io.IOException e { throw new java.rmi.UnmarshalException error unmarshalling arguments, e; } catch java.lang.ClassNotFoundException e { throw new java.rmi.UnmarshalException error unmarshalling arguments, e; } finally { call.releaseInputStream ; } boolean result = server.printDocumentparam_DocumentDescription_1; try { java.io.ObjectOutput out = call.getResultStreamtrue; out.writeBooleanresult; } catch java.io.IOException e { throw new java.rmi.MarshalException error marshalling return, e; } break; } } } Lets look at the arguments of this method first. The method takes an instance of Remote , a RemoteCall , an int , and a long . These arguments have the following meanings: • The instance of Remote is actually an instance of NullPrinter . • RemoteCall is an object that encapsulates a socket connection. The instance of RemoteCall being passed is a connection to a particular client. • The integer is mapped to a particular method on the server. That is, when rmic compiles the stub and the skeleton, it numbers all the methods. Afterwards, instead of passing the method name, it passes the associated integer. This saves bandwidth and also makes the skeleton more efficient by allowing it to perform method dispatch based on integer comparisons, rather than using string comparisons. • The long is an integrity check. Each method defined in NullPrinter has a unique long associated with it. This long is a hash of the method name and all the arguments. Sending this hash, along with the method number, helps to prevent versioning problems. So what does this method do? It essentially contains marshalling and demarshalling code, similar to the code written by hand for the socket-based version of the printer server.

4.3.3 The Data Objects