TransparentProxy < Communications < TWiki

TWiki . Communications . TransparentProxy

-- JohnCatherino - 08 Jun 2006

Using remote objects as if they were local

This example will demonstrate how to use the TransparentItemProxy from the cajo project.

Despite the potentially complicated sounding name, its use is both surprisingly easy, and astonishingly powerful.

First let us define a common interface, shared between client and server.

Of course, we can share as many interfaces as we like, even for the same class, the client and server can even have the interface in different packages:

Duck.java


public interface Duck {
   boolean looks();
   boolean walks();
   boolean talks();
}

Next let's create a simple server POJO, implementing this interface, which we would like to be remotely callable:

DuckServer.java


import gnu.cajo.invoke.Remote;
import gnu.cajo.utils.ItemServer;

public class DuckServer implements Duck {
   public boolean looks()  {
      System.out.println("hi there!");
      return true;
   }
   public boolean walks()  {
      System.out.println("waddle waddle");
      return true;
   }
   public boolean talks() {
      System.out.println("quack quack!");
      return true;
   }
   public static void main(String args[]) throws Exception { // simple unit test
      Remote.config(null, 1198, null, 0); // use cajo port 1198
      ItemServer.bind(new DuckServer(), "Donald");
      System.out.println("duck server running");
   }
}
Now let's create a test server directory; and in it place the common interface Duck, the server object DuckServer, and of course, the tiny 40 kB cajo.jar library.

The server files can be compiled as follows:

javac -classpath cajo.jar;. DuckServer.java

Now let's start up the server, it will require a command line input like the following:

java -classpath cajo.jar;. DuckServer

OK. Now let's create a simple client unit test; to connect to, and use the duck server object:

DuckClient.java


import gnu.cajo.utils.extra.TransparentItemProxy;

public class DuckClient { // try out DuckServer
   public static void main(String args[]) throws Exception {
      Duck duck = (Duck)TransparentItemProxy.getItem(
         "//serverHost:1198/Donald",
         new Class[] { Duck.class }
      );
      System.out.println("looks like = " + duck.looks());
      System.out.println("walks like = " + duck.walks());
      System.out.println("talks like = " + duck.talks());
   }
}
Note: the serverHost portion of the string in the getItem call, must be replaced, with the acutal host name, or IP address of the server.
Now let's create a test client directory; on either the same, or a different physical machine, and in it place the common interface Duck, the client object DuckClient, and likewise, the cajo library.

Similarly, compile the client files:

javac -classpath cajo.jar;. DuckClient.java

Now let's start up the client, it will require a command line input like the following:

java -classpath cajo.jar;. DuckClient

This will result in the following client console output:

looks like = true
walks like = true
talks like = true
and the following server console output:
hi there!
waddle waddle
quack quack!

as the client invokes each method of the server object, with the exact syntactic transparency, as if it were local.

Note: As mentioned previously, a server object is free to create and implement as many service interfaces as it wishes, to group its functional concerns; however the client also gets the unique ability to define its own interfaces to the service, by picking and chosing from any of the methods defined by the service object. This is an extremely powerful concept, known as dynamic client-side subtyping. It can be quite a head-spinner, but it is well worth taking a minute to ponder the significance of it.

Also Note: Whilst all classes in this example are in the unnamed package; much unlike all-local Java: Both the client and the server are free to place their classes and interfaces into whatever packages they wish, without affecting the other, in any way.

This page was an example of using a remote object locally by reference; there is also a way to use a remote object locally by value.

----- Revision r3 - 04 Aug 2007 - 22:46:57 - JohnCatherino