SDSU CS 696 Emerging Technologies: Java Distributed Computing
Spring Semester, 1999
Voyager Agent Basics
Previous    Lecture Notes Index    Next    
© 1999, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 06-May-99

Contents of Doc 34, Voyager Agent Basics


References

ObjectSpace Voyager ORB 3.0 Developer Guide, ObjectSpace, 1999

Doc 34, Voyager Agent Basics Slide # 2

Starting Voyager

The Voyager orb can be started on the command line or in a program. In a program you use the Voyager.startup() methods

Program Start up

com.objectspace.voyager.Voyager Static Methods
addSystemListener(SystemListener listener) 
getSystemThreadGroup() 
getVersion() 
removeSystemListener(SystemListener listener) 
shutdown() 
startup() 
startup(java.lang.Object object, java.lang.String url) 
startup(java.lang.String url) 

SystemListener Interface
shutdown(SystemEvent event) 
startup(SystemEvent event) 

Doc 34, Voyager Agent Basics Slide # 3
Program Start up Example
import com.objectspace.voyager.Voyager;
import com.objectspace.voyager.SystemEvent;
import com.objectspace.voyager.SystemListener;
public class StartupTest implements SystemListener
   {
   public static void main(String[] arguments )
      {
      try
         {
         System.out.println( "Start program" );
         Voyager.addSystemListener( new StartupTest() );
         System.out.println( "Call start up" );
         Voyager.startup( "tcp://rohan.sdsu.edu:6000" );
         System.out.println( "Call shut down" );
         Voyager.shutdown(  );
         System.out.println( "Good by" ); 
         }
      catch (Exception voyagerProblem )
         {
         voyagerProblem.printStackTrace();
         }
      }
   
   public void shutdown( SystemEvent goingDown )
      {
      System.out.println( "Going down" );
      }
   public void startup( SystemEvent starting )
      {
      System.out.println( "Starting up" );
      }
   }

Doc 34, Voyager Agent Basics Slide # 4
Command Line Arguments

url
the url, typically a port, on which to start server
-a <file>
process lines in <file> as arguments
-b <classname>
load and start this application
-c <url>
enable network classloading from specified url
-i <interpreter>
use this interpreter instead of java
-l <string>
log level (silent, exceptions, verbose)
-m <idl> <java>
map idl entity to/from java class
-q
quiet mode, do not display copyright on startup
-r
enable resource (class file) serving
-s
install voyager security manager
-t <int>
the maximum thread pool size
-v
print version information and exit
-x
pass remaining parameters to the java interpreter

voyager 8989 -r


Doc 34, Voyager Agent Basics Slide # 5

Naming Service


Voyager has its own naming service and also supports RMI registry, CORBA naming service, and JNDI. The latter two are not available in the free version of Voyager.

com.objectspace.voyager.Namespace

Static Methods
bind(java.lang.String name, java.lang.Object object) 
lookup(java.lang.String name) 
rebind(java.lang.String name, java.lang.Object object) 
setServerURL(java.lang.Object obj)
Used only in lightweight clients (applets) to be able to use the applet server machine as a proxy for a naming service on a different machine.
unbind(java.lang.String name) 

RMI & Voyager


Voyager programs can be uses as RMI clients and RMI servers

As RMI Client
The following voyager code will access an RMI server registered with a RMI register running on port 5645 on eli.sdsu.edu

Ifoo aFooStub = 
   (Ifoo) Namespace.lookup( "rmi://eli.sdsu.edu:5645/myFoo" );


As RMI Server

The following code will register a voyager server with rmiregistry running on eli on port 5645. The aBarObject’s class can not extend UnicasteRemote. See Voyager manual page 126 for details on classpath. See page 263 for an example.

Namespace.bind( "rmi://eli.sdsu.edu:5645/myBar", aBarObject );

Doc 34, Voyager Agent Basics Slide # 6

Modile Code


The of() method in com.objectspace.voyager.mobility.Mobility returns the IMobility facet of an object. The object must be serializable in order to move the object to a different JVM.

com.objectspace.voyager.mobility.Imobility

moveTo(java.lang.Object destination)
Move the receiver to the JVM containing the specified object
moveTo(java.lang.String destinationURL)
Move the receiver to the JVM specified by the URL.
   public static void mobile() throws Exception
      {
      Voyager.startup();
      String serverClass =  "whitney.voyager.examples.hello.HelloImpl";
      Proxy aProxy =  Factory.create( serverClass);
      Hello helloProxy = (Hello) aProxy;
      System.out.println( helloProxy.sayHello());
      IMobility mover = Mobility.of( helloProxy );
      mover.moveTo( "//eli.sdsu.edu:8000" );
      System.out.println( helloProxy.sayHello());
      mover.moveTo( "//fargo.sdsu.edu:8000" );
      System.out.println( helloProxy.sayHello());
      Voyager.shutdown();
      }

Doc 34, Voyager Agent Basics Slide # 7

moveTo() Explained

This is taken from page 46-47 of Voyager ORB 3.0 Developer Guide.

1 Handling Messages
Current messages to the object are allowed to complete
New messages to the object are suspended
The code can only detect method calls that are synchronized, so do not attempt to move an object that might be executing non-synchronized methods.

2. Moving the Object
The object is serialized and sent to the new location
This means that if the object is not serializable an exception will be thrown. You may wish to consider using proxies in the objects fields to reduce serializable problems. It also means that all the fields of the object are serialized and sent also.
java.rmi.Remote and com.objectspace.voyager.IRemote are ignored
This means that a Voyager object that is also an RMI server can be moved.

3. Keep forwarding address
The new addresses of the object and all of its non-transient parts are cached at the old location.

4. The old object is destroyed.

5. Suspended messages sent to the old object are resumed.

6. Updating old proxies
When a message sent via a proxy arrives at the old address of a moved object, a special exception containing the object’s new address is thrown back to the stale proxy. The proxy traps this exception, rebinds to the new address, and then resends the message to the updated address. If the program at the old location crashes before a stale proxy is updated, the stale proxy is unable to successfully rebind and a message sent via the proxy generates an ObjectNotFoundException.

7. moveTo() returns
If an exception occurs in this process, the old object is restored to its original condition, suspended messages are resumed, and the exception is rethrown wrapped in a MobilityException.

Doc 34, Voyager Agent Basics Slide # 8

Move Notification


Some objects need to be notified when they are about to be moved. Some object may need special processing before moving or after arriving. Some object may need the ability to cancel a move request.

com.objectspace.voyager.mobility.IMobile

An object that implements this interface will be informed when it is being moved with the following methods.
Note I have not been able get this to work yet. I have not determined if this a bug or an error on my part.
postArrival()
At this point, the copy of the object has become the real object, the object at the source has become the stale object, and the move is deemed successful and cannot be aborted.

postDeparture()
This method is executed on the original stale object at the source, and is typically defined to perform activities such as removing the stale object from persistence. Messages sent to the stale object via a proxy will be redirected to the new object, so postDeparture() should not utilize proxies to the original object or any of its facets. Note that because the user-supplied callback on the new object is executed using a fresh thread, it is possible for this postDeparture() to be executing concurrently with the user-supplied callback.

preArrival()throws MobilityException
This method is executed on the copy of the object at the destination. If the method throws a MobilityException, the move is aborted and no more IMobile callbacks occur

preDeparture(String source, String destination) throws MobilityException
This method is executed on the original object at the source. If the method throws a MobilityException, the move is aborted and no more IMobile callbacks occur.


Doc 34, Voyager Agent Basics Slide # 9

Mobile Agents


Use the com.objectspace.voyager.agent.Agent class to turn an object into an agent.

com.objectspace.voyager.agent.AgentMethods
static IAgent get(java.lang.Object object) 
If the specified object implements IAgent, return the object.
static IAgent of(java.lang.Object object) 
If the specified object implements IAgent, return the object.

com.objectspace.voyager.agent.IAgentMethods
getHome() 
getResourceLoader() 
isAutonomous() 
moveTo(Object destination) 
moveTo(Object destination,  String callback) 
moveTo(Object destination, String callback, Object[] args) 
moveTo(String destination) 
moveTo(String destination, String callback) 
moveTo(String destination, String callback, Object[] args) 
setAutonomous(boolean flag) 
setResourceLoader(IResourceLoader resourceLoader)

Doc 34, Voyager Agent Basics Slide # 10

Agent Example

package whitney.voyager.examples.agent;
public interface IHello
   {
   String sayHello();
   }

Doc 34, Voyager Agent Basics Slide # 11

HelloAgent

package whitney.voyager.examples.agent;
import java.net.InetAddress;
import com.objectspace.voyager.agent.*;
import com.objectspace.voyager.mobility.*;
import com.objectspace.voyager.*;
public class HelloAgent implements IHello, java.io.Serializable
   {
   private int count = 0;
   
   public  String sayHello() 
      {
      return  "Hello World from " + getHostName() + " count " +  count++;
      }
   public void move( String newAddress ) throws MobilityException
      {
      System.out.println( "Start move" );
      IAgent agentProxy = Agent.of( this );
      agentProxy.moveTo( newAddress, "movedDone" );
      }
   
   public void movedDone()
      {
      System.out.println( "I have moved" + sayHello() );
      IAgent agentProxy = Agent.of( this );
      
      //rohan host name problem forced this odd check to see if we are home
      if ( getHostName().startsWith( "local" );
         System.out.println( "I am home" );
      else
         try
            {
            System.out.println( "Going home" );
            move( agentProxy.getHome() );
            }
         catch (MobilityException moveProblem )
            {
            System.out.println( "Trouble moving" );
            moveProblem.printStackTrace();
            }
      }

Doc 34, Voyager Agent Basics Slide # 12
HelloAgent Continued
   public static void main( String[] arguments)
      {
      try 
         {
         Voyager.startup( "8000" );
         String serverClass =  "whitney.voyager.examples.agent.HelloAgent";
         HelloAgent bond = new HelloAgent();
         System.out.println( bond.sayHello());
         bond.move( "tcp://fargo.sdsu.edu:8000" );
         
         // No shutdown to make sure the orb will get the return agent
         } 
      catch (Exception e) 
         {
         System.out.println("HelloServer err: ");
         e.printStackTrace();
         }
      }
   }

   protected static String getHostName()
      {
      try
         {
         return InetAddress.getLocalHost().getHostName();
         }
      catch (java.net.UnknownHostException who)
         {
         return "Unknown";
         }
      }

Doc 34, Voyager Agent Basics Slide # 13
Output on Rohan
Hello World from localhost count 0
Start move
I have movedHello World from localhost count 2
I am home


Output on Fargo
I have movedHello World from fargo.sdsu.edu count 1
Going home
Start move


Doc 34, Voyager Agent Basics Slide # 14

Voyager and Rohan


Voyager is located in /opt/voyager3/ on rohan.

You must add to your path /opt/voyager3/bin

You must add to your classpath /opt/voyager3/lib/voyager.jar to your classpath

Voyager and Rohan’s local host Problems
Voyager has the same problem with rohan’s host file setting as RMI. To use voyager on rohan or moria you must always explicitly reference rohan’s name. To state a voyager process on rohan via the command line use:

voyager tcp://rohan.sdsu.edu
or
voyager tcp://rohan.sdsu.edu:portNumber
To start a voyager process on rohan from inside a program use:

Voyager.startup( "tcp://rohan.sdsu.edu:6000" );


Copyright ©, All rights reserved.
1999 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.

Previous    visitors since 06-May-99    Next