The Artima Developer Community
Sponsored Link

The Architecture of Aglets
The Inner Workings of an Agent Technology
by Bill Venners
First Published in JavaWorld, April 1997

<<  Page 3 of 4  >>


How to write an aglet
The process of writing an aglet is in many ways similar to the process of writing an applet. To create an applet, you subclass class Applet. To initialize an applet, you override the init() method, the starting point for any applet. You can use init() to build the user interface of the applet. If you wish, you can fire off other threads from init(). If you do this, you also may override stop() and start() to stop and restart your threads when the browser leaves and returns to the Web page. If you don't create any threads in init(), your applet likely will get at least one thread just because class Applet descends from class Panel. The AWT user-interface library of which Panel is a part will provide whatever threads are needed to run the user interface you create in init().

The aglet development and run-time environments provide a library of Java classes that support the creation and running of aglets. To create an aglet, you must subclass class Aglet, which includes several methods you can override to customize the behavior of your aglet. The aglet's counterpart to the init() method of applets is the onCreation() method. To initialize an aglet, you override onCreation(). The onCreation() method is invoked only once in an aglet's lifetime and should be used only for initialization.

The aglet also has a run() method, which represents the entry point for the aglet's main thread. This is similar to the main() method of a Java application, except that run() is invoked each time an aglet arrives at a new aglet host. For example, if you designed a CatAglet that visits nine different aglet hosts looking for MouseAglets, onCreation() would be invoked only once, when the CatAglet was first instantiated at its first host. Once onCreation() completed, run() would be invoked. Each time the CatAglet arrived at a new host, a method called onArrival() would be invoked to perform any initialization. Once onArrival() completed, run() would be invoked to get the aglet started again at the new host.

Starting run() again each time an aglet is brought to life illustrates the inability of aglets to transmit the state of their execution stacks. For example, imagine a HealthyAglet whose run() method periodically invokes a method named walk(). If, as it is walking, the HealthyAglet is serialized and transmitted to another host, it wouldn't by default continue executing where it left off in walk(). It would start over again at the beginning of run(). Thus, when the aglet is informed that it is about to be serialized, it would need to record on the heap that it is walking -- perhaps in an instance variable of HealthyAglet. That instance variable would be serialized and would migrate with the aglet. When run() is invoked to start the aglet's new life, the run() method would check the instance variable, see it was walking beforehand, and call walk().

The callback model
Before any major event in an aglet's life, a "callback" method is invoked to allow the aglet to prepare for (or refuse to partake in) the event. This is how an aglet learns that it is about to be serialized. For example, before an aglet is dispatched to a new location, the aglet's onDispatch() is invoked. This method indicates to an aglet that it is about to be sent to a new host, the URL of which is specified as a parameter to onDispatch(). In the body of onDispatch(), the aglet must decide whether or not to go. If the aglet decides it doesn't want to go, it throws an exception. If it decides to go, it must complete any unfinished business and prepare its state for serialization. When it returns from onDispatch(), its state will be serialized and all its threads terminated. The class files and serialized state will then be sent to the new host, where the aglet will be resurrected.

The method onDispatch() is a "callback" method because the aglet host invokes it some time after another method, dispatch(), is invoked. An aglet can invoke dispatch() on itself or on another aglet. This callback model for aglets is similar to that of windowing user interfaces. To repaint an AWT component, for example, you invoke the component's repaint() method. At some point later, the system calls back the component's update() method, which in turn calls paint().

The Aglet class defines these five callback methods, which you can override to customize the behavior of your aglet:

onCloning() -- called before a clone operation
onDispatch() -- called before a dispatch
onReverting() -- called before a retraction
onDeactivating() -- called before a deactivation
onDisposing() -- called before a dispose operation (Unlike real life, an aglet can throw an exception if it doesn't want to die.)

For each of these processes, the Aglet class has a corresponding method that triggers the action: clone(), dispatch(), retract(), deactivate(), and dispose(). Some time after these are called, the aglet host will invoke the appropriate callback method.

Each time an aglet begins execution at a host, the host invokes an initialization method on the aglet. When the initialization method returns, the host invokes run(). Depending on the event that precipitated the aglet's new life, the aglet host will choose to invoke one of these four initialization methods:

onCreation() -- called the first time an aglet springs to life
onClone() -- called on a clone after a clone operation
onArrival() -- called after a dispatch or a retraction
onActivation() -- called after an activation

<<  Page 3 of 4  >>

Sponsored Links

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us