Version 0.2
Programming Mobile Agents in JavaTM
- With the Java Aglet API
Danny B. Lange and Mitsuru Oshima © 1997 

Chapter 2

Anatomy of an Aglet

After reading this chapter you should have a basic understanding of the anatomy of an aglet. You will learn about the methods in the aglet that may be overridden by the programmer. These methods are systematically invoked by the system as important events in the life of an aglet. We will show you the principles for using these methods, including important information about the order in which they are invoked by the system when specific events take place. With this knowledge, you should be in position to create aglets that can perform simple tasks on remote computers. 

Let us use the aglet's life cycle as a starting point for this chapter. What can happen to an aglet during its lifetime? Many things --- but first it has to be created. An aglet is created as an instance of an aglet class. This is the normal way to create an object in a programming language such as Java. But actually, there is another way to create an aglet, which is by cloning an existing aglet. This will result in the creation of a twin aglet. Now that one or more aglets exist, we can send them (or dispatch them, as we say) on a trip to some remote site. Having dispatched an aglet, we can wait for it to come back or we can force it back by retracting it. When the aglet has safely returned home we may store it on a hard disk for later use, in which case we say that we have deactivated the aglet. Later, we can wake it up by activating it. Finally, if the aglet is of no use any longer we can simply choose to dispose of it. 

The main events in the life of an aglet can thus be categorized as follows: These categories will make convenient titles for the sections of this chapter.

Aglet Creation

To do anything with an aglet you obviously first have to create it. There are essentially two ways of creating an aglet: either you instantiate it from an aglet class or you clone an existing aglet. We will describe both ways, starting with class instantiation.

Aglet Creation

Class Instantiation

The aglet is created in a context, where it will spend most of its life. When it moves from machine to machine, it really moves from context to context. You can regard a context as a uniform environment for the aglet. No matter whether the aglet is executing on a PC with Windows or on a Unix workstation, it is guaranteed a fixed set of services from the context. One of these services, which we will demonstrate, is instantiation of new aglets from a given aglet class. For an aglet to instantiate new aglets it needs access to its current context. It can do so by calling the getAgletContext method in its own interface.
public final AgletContext getAgletContext()
    Gets the context in which the aglet is currently executing. 
For example, if an aglet executing in a given context wished to create an instance of the SomeAglet class located on the same machine, it would first have to get the current context and then subsequently invoke the createAglet method in that context. The resulting program line in the aglet would look somewhat like this:
getAgletContext().createAglet(getCodeBase(), "SomeAglet", null);
The createAglet method has three arguments. The first argument, which defines the code base of the aglet, is a URL; the second is the name of the aglet class file; and the third consists of a possible initialization argument for the coming aglet. A full description of the createAglet method can be found in the chapter about the aglet context. 

Do not attempt to instantiate the aglet directly from its constructor by using the new statement in Java. It simply will not work! The aglet will not be properly initialized and its behavior will be largely unpredictable. 

Though the aglet context will control the creation of the new aglet, this does not mean that you as an aglet programmer have no influence over it. There are several "hooks" to customize the behavior of the aglet during its creation. In fact, these hooks are methods that you can override in the aglet subclass to implement the desired behavior. Three methods are of particular interest here: the aglet's constructor, onCreation(), and run()
protected Aglet()
    Constructs an uninitialized aglet. This method is called only once in the life cycle of an aglet. As a rule, you should never override this constructor. Instead, you should override onCreation() to initialize the aglet upon creation.
public void onCreation(Object init)
    Initializes the new aglet. This method is called only once in the life cycle of an aglet. Override this method for custom initialization of the aglet.
public void run()
    Is the entry point for the aglet's own thread of execution. This method is invoked upon a successful creation, dispatch, retraction, or activation of the aglet.
These methods are automatically invoked by the context during the creation of the aglet. Two of them, onCreation and run, provide yout with an elegant way of customizing the aglet creation. However, to take full advantage of this mechanism, it is necessary to understand how these methods collaborate. We will use method collaboration diagrams to illustrate this.

The createAglet method in the aglet context is called. Its execution is represented by a horizontal blue bar. During the execution, createAglet() will create an instance of the given aglet class, which is seen as an invocation of the aglets constructor (Aglet()). The execution of the aglet code is represented by horizontal green bars. Notice that execution of createAglet() is suspended (the patterned part of the blue bar) while the constructor is executing and that it resumes only when execution of the constructor is complete. When the aglet instance has been constructed, onCreation() is invoked, and when that has been executed, run() is invoked. The execution of onCreation() and run() takes place in different threads from the original thread of createAglet(), and execution of onCreation()is guaranteed to finish before that of run() starts. Parallel execution is represented by the overlapping of two or more bars.

Creation Method Collaboration

Let us move on to an example in which we let the aglet, CreationExample, create an instance of the aglet class named CreationChild. CreationExample extends the Aglet class:
import aglet.*;

public class CreationExample extends Aglet {
   public void run() {
      try {
         getAgletContext().createAglet(getCodeBase(), "CreationChild", null);
      } catch (Exception e) {
         System.out.println(e.getMessage());
      }
   }
}
The only method that this aglet implements is its run method which calls for the aglet's own context to create an aglet of the CreationChild class. Notice that the program catches any exception thrown during the creation of the aglet and prints out the error message. CreationChild itself extends the Aglet class and overrides three methods: the constructor, onCreation, and run. The systematic invocation of these methods is demonstrated by the console output they generate.
import aglet.*;

public class CreationChild extends Aglet {
   public CreationChild() {
      // Print to the console...
   }

   public void onCreation(Object init) {
      // Print to the console...
   }

   public void run() {
      // Print to the console...
   }
}
Full source code: CreationExample.java and CreationChild.java

Exercise

Run the CreationExample aglet in your favorite aglet viewer. Carefully study the output on the console window and compare it with the method collaboration diagram for aglet creation. Does it match?

Aglet Cloning

Now, let us move on to an alternative way of creating new aglets. If you already have an aglet in your context, you can create its twin by using the aglet's clone method. A successful invocation of this method on a given aglet will create an identical copy (i.e., clone) of it in its current aglet context. Note that this method does not return the clone directly, but instead returns the aglet's proxy to you. The proxy is a placeholder for the aglet, serving to shield it from direct access to its public methods. You will hear more about the aglet proxy later.
public final Object clone()
    Clones the aglet and the proxy that holds the aglet. Notice that it is the cloned aglet proxy which is returned by this method. 
For an aglet to clone itself, it just has to call clone(). Notice, however, that most systems will allow only trusted aglets to clone themselves. In general, you do not want untrusted aglets to multiply on your machine in an uncontrolled way that could be used in a denial of service attack on your system. This will also prohibit (accidental) cascades of cloning aglets in the network.

Two methods in the aglet allow you to customize and control the cloning process. The first, onCloning, is called in the aglet that you attempt to clone. The default implementation of onCloning() will throw a SecurityException when called. To enable cloning, you can simply override this method with an empty body. The second method, onClone, can be used to initialize the clone. 
public void onCloning()
    Is called when you attempt to clone an aglet. The default implementation of this method throws a SecurityException to avoid accidental cloning. Subclasses may override this method to implement any actions that should be taken in response to a cloning request. 
public void onClone()
    Initializes the cloned aglet. Override this method for custom initialization of the cloned aglet.
So how do these methods collaborate? Initially, the aglet's clone method is called. The execution this method is represented by the topmost horizontal green bar. Let the green bars represent execution in the aglet that is being cloned, and let the red bars represent the resulting aglet clone. clone() will invoke the onCloning method in the aglet that is to be cloned. On completion of this method, clone() will resume execution and create the twin aglet. The very first method to be invoked in a separate thread of execution in this new aglet will be the onClone method, followed by the run method. 

Clone Method Collaboration

In this example we let the CloningExample aglet clone itself. CloningExample extends the Aglet class and overrides three methods: onCloning, onClone, and run. Notice that we have added to the class a Boolean field, _theClone. This field is used to distinguish between the parent aglet and its cloned twin. It works as follows. Initially, the value of the field is set to false. When the aglet is cloned, the clone will inherit this field and its value which remains false. Since we are guaranteed that onClone() will be invoked only in the clone and that this will occur before run() is invoked, we can safely let the onClone method toggle the value of the _theClone field. In the run method it is now safe to use the _theClone field to prevent the clone from starting to clone.
import aglet.*;

public class CloningExample extends Aglet {

   private boolean _theClone = false;

   public void onCloning() {
      // Print to the console...
   }

   public void onClone() {
      _theClone = true;  //-- Yes, I am the clone.
      // Print to the console...
   }

   public void run() {
      if (!_theClone) {
         // The parent runs here...
         try {
            clone();
         } catch (Exception e) {
            System.out.println(e.getMessage());
         }      
      } else {
         // The clone runs here...
      }
   }
}
Full source code: CloningExample.java.

Exercise

Run the CloningExample aglet while studying the output in the console window. Compare to see if the output actually corresponds to the method collaboration diagram for aglet cloning.

Aglet Disposal

The aglet takes up various resources while it is in an aglet context. It is therefore good aglet ethics to properly dispose of the aglet after it has fulfilled it task. You should always remember that most aglets will perform their tasks at remote servers as guests, and that as such they are obliged to minimize their consumption of the host' resources. 

The system will reclaim all threads belonging to an aglet that is disposed of. In addition, the aglet context will release all of its resources that are tied to that aglet. In doing so, it will eliminate all references between the context and the aglet to be disposed of. However, there is no guarantee that the memory allocated by the aglet will be immediately deallocated. The Java garbage collector will clear away the aglet when all references to it have been eliminated, including references from other aglets. 

Dispose Aglet

For the aglet to dispose of itself, it should invoke its dispose method. Notice that this method is final, which means that you cannot override it and change its meaning. 
public final void dispose()
    Destroys and removes the aglet from its current aglet context. A successful invocation of this method will kill all threads created by the given aglet. 
A call to dispose() will immediately lead to invocation of the onDisposing method, which is your hook for customizing the disposal process. You can override this method with any actions that should precede the actual disposal of the aglet. For example, you may use the method to allow the aglet to prepare for its own disposal by closing associated files and windows.
public void onDisposing()
    Is called when an attempt is made to dispose of the aglet. Subclasses may override this method to implement actions that should be taken in response to a request for disposal. 
This method collaboration diagram illustrates what happens when the aglet disposes of itself. In an aglet's thread of execution, which may be simultaneous to the execution of its run method, it invokes the dispose method, which in turn invokes the onDisposing method. On the completion of the latter, all threads created by the given aglet are killed. This includes the initial call to dispose(), as long as it is executed by one the aglet's own threads.

Dispose Method Collaboration

DisposalExample is an example of an aglet that disposes of itself immediately after it has been created. That is, as soon as the aglet is created and its run method is called, it invokes dispose(). The onDisposing method is called and the aglet disappears. 
import aglet.*;

public class DisposalExample extends Aglet {

   public void onDisposing() {
      // Print to the console...
   }

   public void run() {
      try {
         dispose();
         // You should never get here!
      } catch (Exception e) {
         System.out.println(e.getMessage());
      }      
   }
}
Full source code: DisposalExample.java.

Exercise

Run the DisposalExample aglet while comparing the console output with the method collaboration diagram for aglet disposal.

Aglet Mobility

There are two ways to move an aglet. One is to dispatch (push) it to a remote location. More specifically, dispatching the aglet means requesting it to go to another location to continue its execution there. The other way to move an aglet is to retract (pull) it from a remote host. That is, by retracting the aglet, we are requesting it to return from some remote location. Retraction often follows a previous dispatch of the aglet to the given host.

Dispatch and Retract Aglet

Dispatching an Aglet

The dispatch method and the Uniform Resource Locator (URL) are your tools for requesting an aglet to visit a remote machine. Like the dispose method, dispatch() cannot be overridden. 
public final AgletProxy dispatch(URL destination)
    Dispatches the aglet to the location (host) specified by the destination argument. 
The URL is a standard way of specifying a remote server on the Web. Besides host and domain names, the URL also includes information about the particular protocol to be used for communicating with the remote server. In the examples in this book we use atp (Agent Transfer Protocol) as a network protocol for dispatching aglets. The dispatch method does not force you to use a specific protocol. Your choice of protocol depends entirely on the set of protocols supported by the particular implementation of the Java Aglet API that you are using and of the protocols supported by the remote server. The following program line is an example of a dispatch call with an associated URL using the atp protocol to dispatch the aglet to a server at some.host.com: Calling dispatch() on an aglet will immediately lead to the invocation of its onDispatching method. This method is a hook that allows you to customize the process of dispatching the aglet. You can override it to allow the aglet to finish its current task and prepare it for the trip to its next destination. The URL of the next destination is given by the destination argument. Upon successful invocation of dispatch(), the onArrival method is called, followed by run(). The onArrival method can be used to initialize the aglet once it has arrived at the new destination.
public void onDispatching(URL destination)
    Is called when an attempt is made to dispatch the aglet. Subclasses may override this method to implement actions that should be taken in response to a dispatch request. For example, if you want to create an immobile (stationary) aglet, override this method to throw a SecurityException.
public void onArrival()
    Initializes the newly arrived aglet. Subclasses may override this method to implement actions that should be taken on arrival of the aglet at a new host. 
The diagram below illustrates how a set of dispatch-related methods collaborate. The green bars represent the aglet's execution before it is dispatched, and the red bars represent its execution at its destination. In an aglet's thread of execution, which may be simultaneous to the execution of its run method, it invokes the dispatch method, which in turn invokes the onDispatching method. On completion of the latter method, all threads created by the given aglet are killed and the aglet is transferred to its destination. The first method to be invoked at the destination is the onArrival method, followed by the run method.

Dispatch Method Collaboration

In this example we let the aglet named DispatchingExample dispatch itself. The example is based on the same template as some of the previous examples in this chapter. DispatchingExample extends the Aglet class and overrides three methods: onDispatching, onArrival, and run. Again we use a Boolean field, _theRemote, to distinguish between the aglet before and after it has been dispatched. When this aglet is created and starts running (run()), it creates a URL for its destination. For simplicity, we let that destination be the current host. When the aglet has been dispatched all its threads will be killed. In other words, you should not expect the execution to return from a successful call to the dispatch method. When the aglet arrives at a new host, onArrival is called and the Boolean field is toggled. The aglet will now remain at this host until it is disposed.
import aglet.*;
import java.net.URL;

public class DispatchingExample extends Aglet {

   private boolean _theRemote = false;

   public void onDispatching(URL url) {
      // Print to the console...
   }

   public void onArrival() {
      _theRemote = true;  //-- Yes, I am the remote aglet.
      // Print to the console...
   }

   public void run() {
      if (!_theRemote) {
         // The original aglet runs here
         try {
            URL destination = new URL((String)getAgletContext().getProperty("location");
            dispatch(destination);
            // You should never get here!
         } catch (Exception e) {
            System.out.println(e.getMessage());
         }
      } else {
         // The remote aglet runs here...
      }
   }
}
Full source code: DispatchExample.java.

Exercise

Run the DispatchExample aglet while comparing the console output with the method collaboration diagram for aglet dispatching.

Exercise

In this example we have used the current host (getHostingURL()) as the destination for the dispatch. Run an additional aglet viewer on a remote host and modify this example aglet to go to that host instead.

Exercise

Make this aglet stationary so that any attempt to dispatch it will result in an exception.

Retracting an Aglet

Sometimes you may not want to wait for an aglet to return on its own, but may prefer to pull it back in a possibly asynchronous fashion. The retractAglet method in the aglet context allows you to do this. The method takes as an argument a URL that specifies the remote host as well the specific aglet that is to be retracted: An aglet is associated with a unique identifier such that every aglet in the network can be uniquely addressed by combining its identifier with its hosting URL. The aglet-specific URL has the following syntax: atp://some.host.com#aglet-identifier. You will hear more about aglet identifiers in a later chapter.

An attempt to retract a remote aglet will lead to the invocation of the onReverting method. This method invocation can be used as a warning that someone is attempting to retract the aglet. Override this method to allow the aglet to prepare for retraction. The method can also be used to prevent retraction. 
public void onReverting(URL remoteURL)
    Is called when someone attempts to retract the aglet from the remote location specified by the remoteURL parameter. Subclasses may override this method to implement actions that should be taken in response to a request for retraction. Override this method to throw a SecurityException if you want to deny a request for retraction.
    Notice: in Alpha 4 the remoteURL is always null.
The retractAglet method in the aglet context is called. Its execution is represented by the horizontal blue bar. The red bars represent the execution threads of the remote aglet. Local invocation of retractAglet() leads to remote invocation of onReverting(). All threads of the remote aglet are killed upon successful completion of the onReverting method. The green bars show the execution threads of the aglet after its return. Execution of the onArrival method is guaranteed to finish before run() starts. 

Retraction Method Collaboration

This example demonstrates how an aglet, RetractionExample, can retract an aglet, RetractionChild, that it has previously dispatched to an aglet server. RetractionExample extends the Aglet class: Here you will see a number of classes and methods that have not yet been introduced, but do not let them confuse you. We will take the body of run() line by line.

In the first line, we use the aglet context to create an instance of the RetractionChild aglet. Creating an aglet in the context returns a reference to a proxy for the new aglet. Later we will use the proxy to dispatch this aglet. In the second line, we retrieve the URL of the hosting aglet server. We will use this URL as destination for the dispatch in the third line. Notice that we use the proxy to dispatch the aglet. When the proxy has successfully dispatched the aglet to the new destination it returns a new socalled remote proxy (a local handle for a remote aglet). We use the identity of the remote aglet to create an aglet-specific URL (host and domain names plus aglet identity) in the fourth line of run()'s body. Finally, in the fifth line everything is set for retracting the aglet.

The RetractionChild aglet extends the Aglet class and overrides three methods: onReverting, onArrival, and run. The systematic invocation of these mehods is demonstrated by the console output they generate. Full source code: RetractionExample.java and RetractionChild.java.

Exercise

Run the RetractionExample aglet while comparing the console output with the method collaboration diagram for aglet deactivation.

Exercise

Modify the retractionChild aglet so that it rejects any attempt to retract it. 

Aglet Storage

The aglet allows you to temporarily store it in secondary storage. To deactivate the aglet means to request it to leave its current context and go to sleep. When the aglet returns to its context we say that it has been activated

Deactivate and Activate Aglet

When you deactivate an aglet you have to specify for how long it should stay deactivated. Notice that the period you specify is only a suggestion to the system. When the aglet is actually activated depends very much on the current implementation you are using and the load on your host. Notice that the deactivate method is final.
public final void deactivate(long duration)
    Deactivates the aglet. The aglet will temporarily be stopped and removed from its current context. It will return to the context and resume execution after the specified period has elapsed.
When deactivate() is called it will immediately invoke the onDeactivating method. You should override this method to allow the aglet to finish its current task before going to sleep. The duration of the aglet's sleep is given in milliseconds by the duration argument. The aglet will be activated after the specified period has elapsed. The onActivation method can be used to initialize the aglet when it is activated. 
public void onDeactivating(long duration)
    Is called when an attempt is made to deactivate the aglet. Subclasses may override this method to implement actions that should be be taken in response to a request for deactivation. 
public void onActivation()
    Initializes the newly activated aglet. Subclasses may override this method to implement actions that should be taken on activation of the aglet. 
The diagram below illustrates how the set of methods related to deactivation and activation collaborate. The green bars represent the aglet's execution before it is deactivated, and the red bars represent its execution after it is activated. In an aglet's thread of execution, which may be simultaneous with the execution of its run method, it invokes the deactivate method, which in turn invokes the onDeactivating method. On completion of the latter method, all threads created by the given aglet are killed and the aglet goes to sleep outside the aglet context. The first method to be invoked at the destination is the onActivation method, followed by the run method.

Deactivate Method Collaboration

The DeactivationExample aglet will deactivate itself for about 10 seconds. DeactivationExample extends the Aglet class and overrides three methods: onDeactivating, onActivation, and run. As in previous examples in this chapter, we use a Boolean field, _activated, to distinguish between the aglet before and after it is activated. When this aglet is created and starts running (run()), it immediately deactivates itself. When this happens, all its threads are killed. In other words, you should not expect the execution to return from a successful call to the deactivate method. The aglet context will automatically wake it up when the 10 seconds have elapsed. When the aglet is activated, its onActivation method is called and the Boolean field is toggled. The aglet will now remain at this host until it is disposed of.  Full source code: DeactivationExample.java.

Exercise

Run the DeactivationExample aglet while comparing the console output with the method collaboration diagram for aglet deactivation.