back to API     back to index     prev     next  

Hello world ! example

This example implements a very simple client-server application. A client object display a String received from a remote server. We will see how to write classes from which active and remote objects can be created, how to find a remote object and how to invoke methods on remote objects.

The two classes

Only two classes are needed: one for the server object Hello and one for the client that accesses it HelloClient.

The Hello class

This class implements server-side functionalities. Its creation involves the following steps:

Here is a possible implementation for the Hello class:



Hello.java
public class Hello {

  private String name;
  private String hi = "Hello world";
  private java.text.DateFormat dateFormat = new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

  public Hello() {
  }

  public Hello(String name) {
    this.name = name;
  }

  public String sayHello() {
    return hi + " at " + dateFormat.format(new java.util.Date())+
        " from node : " + ProActive.getBodyOnThis().getNodeURL();
  }

  public static void main(String[] args) {
    // Registers it with an URL
    try {
      // Creates an active instance of class HelloServer on the local node
      Hello hello = (Hello)org.objectweb.proactive.ProActive.newActive(Hello.class.getName(), new Object[]{"remote"});
      java.net.InetAddress localhost = java.net.InetAddress.getLocalHost();
      org.objectweb.proactive.ProActive.register(hello, "//" + localhost.getHostName() + "/Hello");
    } catch (Exception e) {
      System.err.println("Error: " + e.getMessage());
      e.printStackTrace();
    }
  }
}


Implement the required functionalities

Implementing any remotely-accessible functionality is simply done through normal Java methods in a normal Java class, in exactly the same manner it would have been done in a non-distributed version of the same class. This has to be contrasted with the RMI approach, where several more steps are needed:

Why an empty no-arg constructor ?

You may have noticed that class Hello has a constructor with no parameters and an empty implementation. The presence of this empty no-arg constructor is imposed by ProActive and is actually a side-effect of ProActive's transparent implementation of active remote objects (as a matter of fact, this side-effect is caused by ProActive being implemented on top of a 100% Java metaobject protocol). If no such constructor is provided, active objects cannot be created.

If no constructor at all is provided, active objects can still be created because, in this specific case, all Java compilers provide a default no-arg empty constructor. If a no-arg constructor is provided but its implementation is not empty, unwanted behavior may appear because the no-arg constructor is always called when an active object is created, whatever code the user can write.

Creating the remote Hello object

Now that we know how to write the class that implements the required server-side functionalities, let us see how to create the server object. In ProActive, there is actually no difference between a server and a client object as both are remote objects.Creating the active object is done through instantiation-based creation. We want this active object to be created on the current node, which is why we use newActive with only two parameters. In order for the client to obtain an initial reference onto this remote object, we need to register it in the registry (which is actually the well-known rmiregistry) with a valid RMI URL.

The HelloClient Class

The responsibility of this class is first to locate the remote server object, then to invoke a method on it in order to retrieve a message, and finally display that message.

HelloClient.java
public class HelloClient {

  public static void main(String[] args) {
    Hello myServer;
    String message;
    try {
      // checks for the server's URL
      if (args.length == 0) {
        // There is no url to the server, so create an active server within this VM
        myServer = (Hello)org.objectweb.proactive.ProActive.newActive(Hello.class.getName(), new Object[]{"local"});
      } else {
        // Lookups the server object
        System.out.println("Using server located on " + args[0]);
        myServer = (Hello)org.objectweb.proactive.ProActive.lookupActive(Hello.class.getName(), args[0]);
      }
      // Invokes a remote method on this object to get the message
      message = myServer.sayHello();
      // Prints out the message
      System.out.println("The message is : " + message);
    } catch (Exception e) {
      System.err.println("Could not reach/create server object");
      e.printStackTrace();
      System.exit(1);
    }
  }
}


Looking up a remote object

The operation of lookup simply means obtaining a reference onto an object from the URL it is bound to. The return type of method Proactive.lookupActive() is Object, then we need to cast it down into the type of the variable that holds the reference (Hello here). If no object is found at this URL, the call to Proactive.lookupActive() returns null.

Invoking a method on a remote object

This is exactly like invoking a method on a local object of the same type. The user does not have to deal with catching distribution-related exceptions like, for example, when using RMI or CORBA. Future versions of ProActive will provide an exception handler mechanism in order to process these exceptions in a separate place than the functional code. As class String is final, there cannot be any asynchronism here since the object returned from the call cannot be replaced by a future object (this restriction on final classes is imposed by ProActive's implementation).

Printing out the message

As already stated, the only modification brought to the code by ProActive is located at the place where active objects are created. All the rest of the code remains the same, which fosters software reuse.

Hello World within the same VM

In order to run both the client and server in the same VM, the client creates an active object in the same VM if it doesn't find the server's URL. The code snippet which instantiates the Server in the same VM is the following:

if (args.length == 0) {
  // There is no url to the server, so create an active server within this VM
  myServer = (Hello)org.objectweb.proactive.ProActive.newActive(Hello.class.getName(), new Object[]{"local"});
}

To launch the Client and the Server, just type:

> java org.objectweb.proactive.examples.hello.Client &

Hello World from another VM on the same host

Starting the server

Just start the main method in the Hello class.
> java org.objectweb.proactive.examples.hello.Hello &

Launching the client

> java org.objectweb.proactive.examples.hello.HelloClient //localhost/Hello

Hello World from abroad: another VM on a different host

Starting the server

Log on to the server's host, and launch the Hello class.
remoteHost> java org.objectweb.proactive.examples.hello.Hello &

Launching the client

Log on to the client Host, and launch the client
clientHost> java org.objectweb.proactive.examples.hello.HelloClient //remoteHost/Hello


Copyright © April 2004 INRIA All Rights Reserved.