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

Chapter 3

Aglet Context

This chapter covers one of the key elements of J-AAPI, namely the AgletContext interface. You will learn about the methods that an aglet can invoke in its current context in order to create new aglets, retrieve aglets contained in the same context, and much more.

The AgletContext interface is used by an aglet to get information about its environment and to send messages to the environment and other aglets currently active in that environment. It provides means for maintaining and managing running aglets in an environment where the host system is secured against malicious aglets.

The aglet context is typically created by a system that has a network daemon whose job is to listen to the network for aglets. Incoming aglets are received and inserted into the context by the daemon. Often, a user interface component will provide a graphical or command line interface to the context.

Aglet Context with UI

An aglet belongs at any moment to one and only one context. It can gain access to this context by means of its getAgletContext method: The next section describes in detail methods for aglet creation and proxy retrieval.

Aglet Creation

The only way you can properly instantiate an aglet is within a context. The context provides all aglets with a uniform initialization and execution environment. That is, an aglet relies on services provided by the context to be properly instantiated and initialized. The createAglet method is used to create new aglets.
public abstract AgletProxy createAglet(URL codeBase, String code, Object init) 
    Creates an instance of the specified aglet class. The aglet's class code file can be located on the local file system as well as on a remote server. If the codeBase is null, the context will search for the code in the local system's aglet search path (AGLET_PATH). 
The createAglet method takes three arguments: codeBase, code, and init.
  1. codeBase specifies the base URL of the aglet class file, in other words, the (possibly remote) directory that contains the aglet's code. If this argument is null, then the directories specified in the local host's aglet search path are searched. The aglet search path works in a similar way to Java's class path. It is typically an environment variable that specifies a list of directories to be searched for aglet code files.
  2. code gives the name of the file that contains the aglet's compiled class code. This file is relative to the base URL of the aglet, and cannot be absolute.
  3. init is an object passed on to the aglet's onCreation method.
When an aglet has been successfully created, it is inserted into the current context and started (invocation of onCreation() followed by run()). The method returns a handle (AgletProxy) for the new aglet as soon as the aglet's constructor method finishes.

Code and Code Base

What do we mean by an aglet's code base? Well, it is one of the two arguments necessary to locate the code for an aglet. The codeBase specifies by a URL the (possibly remote) directory that contains the aglet's compiled class code. The second argument, code, is always relative to the base URL and translates the Java package dot notation (My.Package.SomeAglet) into a proper path expression (My/Package/SomeAglet.class). The following table gives some examples of code and code base, and how they are translated into an absolute path for the code file that is actually being loaded:
Code base
Code
Aglet code file actually loaded
file://c:/some/path  Demo  c:\some\path\Demo.class 
atp://some.host/path  Demo  atp://some.host/path/Demo.class 
http://some.host/path  Demo  http://some.host/path/Demo.class 
http://some.host/path  examples.Demo  http://some.host/path/examples/Demo.class 
So what exactly is the purpose of the code base? It plays an important role as a reference point for the aglet's class loader. It is used not only for aglet creation, but also by an aglet when it needs to instantiate new classes (e.g., new SomeClass()) during its execution. In this case, the aglet uses the code base to search for the code file of the indicated class. Say the code base is file://c:/some/path; then the class loader will look for the compiled code of SomeClass in the file c:\some\path\SomeClass.class.

Code Base

In the special case where the code base is null, the local host's aglet search path is used (AGLET_PATH). The workings of this search path are very similar as to those of Java's class path. It defines a list of directories that are to be searched for the specified code file. The following table gives two examples in which the code base is null:
Code base
Code
Aglet code file actually loaded
null  Demo  [AGLET_PATH]/Demo.class 
null  Example.Demo  [AGLET_PATH]/examples/Demo.class 
Notice that code residing in one of the directories specified in Java's class path cannot move along with an aglet when it is dispatched. In other words, you can regard the code that resides in one of these directories as resident host code. Resident code will typically include the aglet system itself. Obviously, it will also include other installed Java applications, since these are often included in Java's class path when they are installed. The rationale behind this is to provide an intuitive way of preventing system/application software from moving along with the aglets. Say your aglets are using JDBC to access local databases. It really would not be practical to transfer JDBC code from host to host, since that code depends on the type of database located on each host. Instead, the aglet should rely on the local version of JDBC.

In the first example in this chapter, we will let the CodeBaseExample aglet create an instance of an aglet whose class code is located in a file named CodeBaseChild.class in the /aglets/aglet-book/examples directory on a remote Web (http) server named www.trl.ibm.co.jp: Full source code: CodeBaseExample.java and CodeBaseChild.java.

In this case the code base is defined as the URL of the remote host, but what if the code of CodeBaseChild is on the local machine instead? Say the code is stored in the local path C:\some\path\CodeBaseChild.class. The solution is simple, since the URL is a powerful abstraction for locations. It covers a wide range of schemes including file, atp, and http. If the code base is in the local file system, you should use the file URL: file://c:/some/path.

The following table summarizes the relationship between the code base URL and the location of the aglet's class file:
Code Base URL
Location
null  A directory in the aglet search path 
file://c:/some/path  A directory in the local file system 
atp://some.host/some/path  A directory on a remote aglet server using the atp protocol 
http://some.host/some/path  A directory on a remote Web server using the http protocol 
If the child's class file always shares code base with its creator, you can increase the degree location transparency by replacing the child's absolute code base with the current code base of the creator. This is particular useful when you are developing and testing the aglets in a different environment from the one where they will be deployed. Use the aglet's getCodeBase() to get the current code base:

Exercise

Copy CodeBaseChild.class to a directory on your local disk. Then modify CodeBaseExample to instantiate the child from the local file system. Finally, try to copy the class file into one of the directories in your local aglet search path. Set the codebase in CodebaseExample to null and confirm that the system is still able to find and instantiate the aglet's code.

Initialization Argument

Notice that the aglet's onCreation method takes a single Object argument. This argument is used to transfer initialization information from the creator to its child. Let us demonstrate this feature by transferring a string of text from the creator (InitExample) and the child (InitChild).  InitExample passes the text string to the child through the third argument in createAglet(). This string is received by InitChild's onCreation method. The fact that this method is guaranteed to complete its execution before run() is started means that it can be trusted to initialize the text field before this field is printed to the console in the run method. Notice that it is necessary to cast the generic init parameter to the actual type of the field (String). Full source code: InitExample.java and InitChild.java.

Proxy Retrieval

In this section we will focus on methods that retrieve aglet proxies for you. As you may, proxies play know an important role as convenient handles for aglets. That is, you can use a proxy to gain access to and communicate with its corresponding (possibly remotely located) aglet. We will cover proxies in depth in the next chapter.

Next, we will demonstrate a number of ways in which you can retrieve proxies from local as well as remotely located aglets.

Proxy Iterator

The first method we will take a closer look at is the getAgletProxies method. This method allows you to iterate the entire set of aglets in the current context.
public abstract Enumeration getAgletProxies() 
    Gets the proxies of all aglets in the current context. The resulting list (enumeration) will also include currently deactivated aglets. 
In this example we use the getAgletProxies method to list the current set of aglets in the following format: The identity, code base, and code name are readily available from the proxy. That is, we can generate this list simply by iterating the set of proxies and for each proxy retrieve the needed information (getIdentifier(), getCodeBase(), and getAgletClassName() in the AgletProxy class).

The getAgletProxies method returns an Enumeration of proxies. Enumeration has two methods that support iteration: hasMoreElements() and nextElement(). This excerpt from the ProxyListing example shows how the list is iterated and how aglet information is retrieved and printed on the console: Full source code: ProxyListing.java.

Getting a Local Proxy

The context also has methods for retrieving the proxy of an aglet if you know the aglet's identity and, if it is not residing in the current context, its location. The first method we will present is for retrieving the proxy of an aglet in the current context.
public abstract AgletProxy getAgletProxy(AgletIdentifier identity) 
    Gets a proxy for an aglet in the current context. The selected aglet is specified by its identity. 
To retrieve a proxy from the current context by the getAgletProxy method, you have to know the exact identity of the corresponding aglet. In the following example, we let an aglet create two other aglets. Because one of these is told the identity of the other, it is able to retrieve the proxy of the other and send it a message.

Proxy Retrieval

First, the parent aglet (RetrievalExample) creates a child (RetrievalChild1) and stores the child's identifier: Next, the parent aglet creates a second child (RetrievalChild2), to which it passes the identity (aid) of the first child: The behavior of the first child is very simple. With only the handleMessage method implemented, it will respond to any message sent to it by printing the message on the console: The second child's onCreation method takes an aglet identifier as its initialization argument. This identifier is stored in the second child's private aid field and later used by the run method. In run() the second child will use the aid field to retrieve the proxy for the first child (also called its brother). Having retrieved the proxy, it will send the "Hello brother" message to the first child: Full source code: RetrievalExample.java, RetrievalChild1.java, and RetrievalChild2.java.

Getting Remote Proxy

Now let us move on to a method that allows us to retrieve the proxy of an aglet hosted in a remote context.
public abstract AgletProxy getAgletProxy(URL host, AgletIdentifier identity) 
    Gets a proxy for an aglet in a remote context. The remote context is identified by its URL, and the aglet is indicated by its identifier. 
To get a proxy of an aglet located in a remote context by the getAgletProxy method, you have to know the URL of the remote context and the exact identity of the aglet. In the following example, we let an aglet create two aglets. One of these aglets is dispatched to a remote context. Because the other one is told of the location as well as the identity of the remote aglet, it is able to retrieve the proxy of the remote aglet and send it a message.

Remote Proxy Retrieval

First, the parent aglet (RemRetrievalExample) creates a child (RetrievalChild1 is reused from the previous example), stores the child's identifier, and dispatches it to a remote context: Next, the parent aglet creates a second child (RemRetrievalChild2), to which it passes the aglet URL (destination and aid) of the dispatched child: The AgletURL class is defined as follows: The second child's onCreation method takes an aglet URL as its initialization argument. The aglet URL is stored in the second child's private url field and is later used by the run method. In run() the second child will use the url field to retrieve the proxy for the remote aglet. Having retrieved the proxy, it will send the "Hello brother" message to the remote aglet: Full source code: RemRetrievalExample.java, RemRetrievalChild1.java, RemRetrievalChild2.java, and AgletURL.java.