Porting Sun RPC to JRPC Direct translation of
SUN ONC RPC to Java(tm) technology
To maintain full
compatibility between Sun RPC and JRPC, it is important to port the
original C code for Sun RPC directly to Java(tm) without major alterations.
Java(tm) is an OO language, it always speaks about classes. C does not have
classes, it has only structs and functions. Fortunately, the Sun RPC
is actually written in an Object-oriented fashion, only in C. In porting
Sun RPC to Java(tm), we were able to identify the object classes used and
their methods in the original C code and perform straightforward mappings
to Java(tm). Once the classes and methods are identified, we can perform
a simple translation of C code to Java(tm), thus maintain maximum compatibility.
Since C does not
have classes, to represent an object with associated method, one has
to use a C struct which contains function pointers, this C struct serves
as an abstract base class, concrete object is created by assigning specific
function pointers to the fields of the struct.
Let's look at the
following core classes in Sun RPC, namely, XDR and CLIENT
XDR classes
This portion of
the original paper is not available online, but can be requested by
customers who licensed JRPC.
The RPC Client
Classes
typedef struct _onc_client_t {
AUTH *cl_auth; /* authenticator */
struct clnt_ops {
enum clnt_stat (*cl_call)(struct _onc_client_t*, u_long,
xdrproc_t, void*, xdrproc_t, void*, struct timeval);
/* call remote procedure */
void (*cl_geterr)(); /* get specific error code */
....
} *cl_ops;
} CLIENT;
//Some fields are ommitted for clarity
Similarly, an RPC
client is represented by the structure named CLIENT, which has method
cl_call() for making an RPC, it also has an important member named AUTH
for authentication purposes.
Just like the
case with XDR, a CLIENT is abstract, it can't be directly used, only
the non-abstract CLIENT created for specific protocols can be used to
call RPC. clnttcp_create() creates a CLIENT handle for the TCP protocol,
which contains a cl_call function pointer (=clnttcp_call) specific to
TCP, in OO language, clnttcp_create() is the constructor for a TCP client.
Similarly, clntudp_create() is the constructor for a UDP client, and
clntudp_call() is the overridden cl_call method.
The following table
shows the direct mapping of the C code to JRPC classes
The Sun RPC has
another function to create a CLIENT, namely, clnt_create(). This function
is a convenience function to create either a TCP or a UDP client based
on the protocol string passed, associated with this there is a macro
CLNT_CALL() which makes RPC on a generic CLIENT.
The C code for
clnt_create() looks like this
CLIENT *clnt_create(
char *hostname, unsigned prog, unsigned vers, char *proto){
IF proto is
"tcp" use clnttcp_create() to create a TCP client
ELSE use clntudp_create()
to create a UDP client
}
The above logic
is straightforwardly mapped
to the constructor of the ClientGeneric class in Java(tm) RPC (extended
to add HTTP protocol)
The client stub
function generated by Sun's rpcgen have prototype as the following
return_type
func ( ARG, CLIENT );
One easily identifies
this as a method func() of a class derived from CLIENT.
The Server and
other classes
The same mapping
rules apply to the server side, we are not going to repeat the discussion
but merely list the mappings in the following table.