Johan Ovlinger
Based on work by
Crista Lopes
RIDL is demjava's aspect language for remote invocation. Basically, it is a wrapper around java's RMI. This in itself is reason enough to use it; it allows the user to access remote objects and operations in a transparent manner. Furthermore, it allows the user to specify how arguments and results are to be passed; by copy (full or partial) or by reference.
RIDL offers nothing that cannot be achieved using RMI, but the same can be said about assembly langauge.
RIDL's main selling point is that it separates out the remote aspect of an application to a separate specification; the behavioral part of the application is the same
for both a remote or local application.
RMI requires a significant reworking of the application when moving to a remote setting.
I always find it easier to learn a new concept with a simple example to illustrate. So here, even before I've defined the terms necessary to describe it, is a small local application, written in the std demjava behavior style.
| 2cTHE BEHAVIOR | |
Counter {
(@
private IntHolder counter;
@)
public void reset(IntHolder i ) (@
System.err.println("reset "+i.toString());
counter = i;
@)
public IntHolder get_next() (@
System.err.println("++"+counter.get_val());
counter.set_val(counter.get_val()+1);
return new IntHolder(counter.get_val());
@)
}
IntHolder {
public String toString() (@
return "IntHolder "+get_val();
@)
}
|
User {
public static void main(String[] args) (@
// ifndef RIDL
Counter c1 = new Counter();
// else
/*
String host1 = args[0];
int port = Integer.parseInt(args[1]);
Counter c1 = (Counter) RIDL_Runtime.RIDL_Naming.
remotenew("Counter",host1,port);
*/
// endif
c1.reset(new IntHolder(10));
for (int i =0;i<10;i++) {
IntHolder i1 = c1.get_next();
System.err.println(host1+" "+i1.get_val());
}
@)
}
|
The application is a really simple one; a counter is created. It is incremented a number of times. Wow. The version shown is a simple vanilla java program.
Now our evil boss comes in and says that all design criteria have changed! Now the counter object should reside be on another machine. All our work is for naught! Ha ha ha!
As the heroes of this little fable, we of course get the last laugh. Armed with our magical RIDLer capabilities, we quickly cobble up a RIDL description file, and make a few minor changes to the application (shown in the ifndef comments), and our counter works on remote machines too.
| THE CD FILE | THE RIDL FILE |
*noparse* User = . *public* Counter = . IntHolder = <val> int. |
portal Counter {
public void reset(IntHolder i)
i: copy ;
public IntHolder get_next()
return: gref;
}
portal IntHolder {
public int get_val();
public void set_val(int val);
}
|
The secret to our magical abilities is the RIDLer. It reads our specification and modifies the behavior and structural aspects (specified by *.beh and *.cd files, resp.). Exactly how this is done not specified here. Crista Lopes's thesis covers these details.
The program we wrote in response to the boss's requirements does the following: a User object resides locally. It creates a remote instance of the Counter on some other machine host1. That machine must be running a RIDL naming service, which is a thin wrapper around RMI's naming service. RIDL's naming service creates an instance of Counter, and returns a remote reference (a so called gref) to User.
User now resets the counter and gets the 10 next numbers. The RIDL specification specifies that reset should pass its initial valu e by copy (for illustrative purposes only). Also, get_next passes its result as a gref.
Enough handholding. Here are the details.
An object can be either local or remote. RIDL deals with remote method invokation- or more accurately, invoking methods (and passing arguments and results) on remote objects. Given a remote object to invoke methods on, we can either pass arguments to that method by copy or as a remote reference.
When something is passed by copy, a copy is made and reinstantiated on the remote machine. Java calls this serialization. RIDL allows the user to specify which part of the object needs to be copied (for some operations, perhaps we know that some part of the object will not be needed).
A gref is a remote reference. The main object resides on the remote machine, and only a proxy object exists locally. The proxy object forwards all method calls to the remote object.
The tradeoff is that passing an object by copy can be slow, but once passed, invoking methods is fast. Some objects require themselves to be unique (either they are too big to copy profusely, or they have semantic reasons to be unique).
Grefs are fast to pass, but method invocation can be slow. Primitive values cannot be passed by gref.
A RIDL specification file is a sequence of portals.
A class needs a portal if it is to be passed as an argument to a remote object's method, or if it is to be a remote object itself.
Portal = "portal" ClassName [PortalBody]. }
PortalBody = "{" MethodList "}".
In addition to just having a portal, a class can also have a portalbody. The portal body specifies which methods can be called on a remote (gref) object. The signature of each method that is to be callable needs to be listed in the portal body.
Optionally, we can specify how an argument or result is passed. The options are remote reference gref, full copy copy, or partial copy copy: traversal-name. Passing by gref, the object stays on the machine it currently resides on, and a pointer to it is passed. This is akin to java remote objects. The partial copy created is exactly the subobject reachable via the given traversal. A full copy is what java serialization offers. The default passing discipline is by full copy.

One of the more annoying aspects about using RMI is that object instatiation is very roundabout. To alleviate this, RIDL offers an object instantiation service.
To use it, the RIDL naming server must be started on a remote machine. It needs to see in its CLASSPATH all the classes it is to be able to instantiate, and needs to be passed a port number to listen to. F.ex to start the naming server on port 1234, you could issue the command:
> java RIDL_Runtime.RIDL_Naming 1234
The class RIDL_Runtime.RIDL_Naming is included in demjava.jar.
To then use this server (supposedly running on host bar) to instatitate an instance of class Foo, one would say
Foo afoo = RIDL_Runtime.RIDL_Naming.remotenew("Foo","bar",1234);
This was illustrated in the earlier example. afoo is a gref (as it doesn't make sense to instantiate an object on a remote machine and return the result by copy), so Foo needs to have a portal specification for this to work.
RIDL also supports an RMI-like naming service (which is hinted at by the name RIDL_Naming). To create an object on a remote machine and bind it to the name ``erik'' (NB: this operation returns void):
RIDL_Runtime.RIDL_Naming.remotenew("Foo","bar",1234,"erik");
We can now look up ``erik'' in that registry by saying:
Foo afoo = RIDL_Runtime.RIDL_Naming.lookup("bar",1234,"erik");
RIDL is enabled by adding a RIDLFILES entry to the project file of your application. For example, if you have your portals in two files foo.ridl and bar.ridl you would add the line RIDLFILES = foo.ridl bar.ridl to your project file.
This document was generated using the LaTeX2HTML translator Version 97.1 (release) (July 13th, 1997)
Copyright © 1993, 1994, 1995, 1996, 1997, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
The command line arguments were:
latex2html -split 2 ridl.tex.
The translation was initiated by Karl Lieberherr on 11/5/1998