Remote Method Invocation

Javassist enables an applet to access a remote object as if it is a local object. The applet can communicate through a socket with the host that executes the web server distributing that applet. However, the applet cannot directly call a method on an object if the object is on a remote host. The javassist.tools.rmi package provides a mechanism for the applet to transparently access the remote object. The rules that the applet must be subject to are simpler than the standard Java RMI.

1. Sample applet

The applet showing below is a simple number counter. If you press the button, the number is increased by one. An interesting feature of this applet is that the object recording the current number is contained by the web server written in Java. The applet must access the object through a socket to obtain the current number.

However, the program of the applet does not need to directly handle a socket. The ObjectImporter provided by Javassist deals with all the awkward programming. Look at the lines shown with red:

Figure 1: Applet

import javassist.tools.rmi.ObjectImporter;

public class CountApplet extends Applet implements ActionListener {
  private Font font;
  private ObjectImporter importer;
  private Counter counter;
  private AlertDialog dialog;
  private String message;

  public void init() {
    font = new Font("SansSerif", Font.ITALIC, 40);
    Button b = new Button(getParameter("button"));
    b.addActionListener(this);
    add(b);
    importer = new ObjectImporter(this);
    dialog = new AlertDialog();
    message = "???";
  }

  public void start() {
    String counterName = getParameter("name");
    counter = (Counter)importer.getObject(counterName);
    message = Integer.toString(counter.get());
  }

  /* The method called when the button is pressed.
  */
  public void actionPerformed(ActionEvent e) {
    message = Integer.toString(counter.increase());
    repaint();
  }

  public void paint(Graphics g) {
    g.setFont(font);
    g.drawRect(50, 50, 100, 100);
    g.setColor(Color.blue);
    g.drawString(message, 60, 120);
  }
}

A Counter object running on a remote host maintains the counter number. To access this object, the applet first calls getObject() on an ObjectImporter to obtain a reference to the object. The parameter is the name associated with the object by the web server. Once the reference is obtained, it is delt with as if it is a reference to a local object. For example, counter.get() and counter.increase() call methods on the remote object.

The definition of the Counter class is also straightforward:

Figure 2: Remote object

public class Counter {
  private int count = 0;

  public int get() {
    return count;
  }

  public int increase() {
    count += 1;
    return count;
  }
}

Note that the javassist.tools.rmi package does not require the Counter class to be an interface unlike the Java RMI, with which Counter must be an interface and it must be implemented by another class.

To make the Counter object available from the applet, it must be registered with the web server. A AppletServer object is a simple webserver that can distribute .html files and .class files (Java applets).

Figure 3: Server-side program

public class MyWebServer {
  public static void main(String[] args) throws IOException, CannotCompileException
  {
      AppletServer web = new AppletServer(args[0]);
      web.exportObject("counter", new Counter());
      web.run();
  }
}

The exportObject() method registers a remote object with the AppletServer object. In the example above, a Counter object is registered. The applet can access the object with the name "counter". The web server starts the service if the run() method is called.


2. Features

The remote method invocation mechanism provided by Javassist has the following features:

With the Java RMI or Voyager, the applet programmer must define an interface for every remote object class and access the remote object through that interface. On the other hand, the javassist.tools.rmi package does not require the programmer to follow that programming convention. It is suitable for writing simple distributed programs like applets.


3. Inside of the system

A key idea of the implementation is that the applet and the server-side program must use different versions of the class Counter. The Counter object in the applet must work as a proxy object, which transfers the method invocations to the Counter object in the server-side program.

With other systems like the Java RMI, the class of this proxy object is produced by a special compiler such as rmic. It must be manually maintained by the programmer.

However, Javassist automatically generates the proxy class at runtime so that the programmer does not have to be concerned about the maintenance of the proxy class. If the web browser running the applet requests to load the Counter class, which is the class of an exported object, then the web server transfers the version of Counter that Javassist generates as a proxy class.