SMI user's guide

Agencies

SMI agencies

Mobile objects/agents are hosted and managed by agencies, instances of class org.objectweb.mobilitools.smi.api.Agency.

The core of SMI consists of execution environments for mobile objects (called agents to stick to MAF specification). An execution environment is an instance of class org.objectweb.mobilitools.smi.api.Agency that we call an agency. It belongs to a region, it has a name (unique in the given region), and it is bound to an authority. Both the region name and the agency name are given as parameters for instantiating an agency. The authority attached to the agency is determined by the user.name system property (i.e. typically the login user name).

The agency is a CORBA server implementing MAF's MAFAgentSystem interface. This server is bound in the CORBA naming service to a globally unique name resulting from a combination of both the region name and the agency name: /MAF/regionA/agency/agency1 (see class org.objectweb.mobilitools.smi.api.Constants).

Agency personalities

For practical reasons (e.g. in order to ease the implementation of some specific agent model), SMI agencies may be customized by personalities. Agency personalities must provide the customized SMI agency with an implementation of two interfaces: This personality feature may be exploited by inheritance or delegation.

Mobile objects/Agents

Agents are implementations of interface org.objectweb.mobilitools.smi.api.MobileObject (and java.io.Serializable).

Agencies have methods for creating and managing any Java object implementing the org.objectweb.mobilitools.smi.api.MobileObject interface. This interface mainly consists of callbacks related to the life cycle of mobile objects. It also enforces that mobile objects implement java.io.Serializable.
A vanilla implementation of interface org.objectweb.mobilitools.smi.api.MobileObject is provided by abstract class org.objectweb.mobilitools.smi.goodies.BasicMobileObject, as a helper class when inheriting is possible.

Accordingly to MAF, agents always reside in a place, and have a unique name combining an identity, an authority and an Agent System Type identifier. When not specified, the agent's authority is the creation agency's authority. The Agent System Type identifier is specific to SMI (see class org.objectweb.mobilitools.smi.api.Constants).

MAF describes agents as autonomous, active objects. SMI does not require mobile objects to be active. If an agent needs to be active, it may use the lifecycle callbacks to start, suspend, resume and stop one or several activities, using Java threads for instance. However, since Java threads can not be serialized, and since several thread management methods are deprecated in Java2 with no substitute, it is highly recommended to be very careful when mixing threads, mobility and communication!
Finally, remember there are ways to make agents active without making a plain use of threads (automata, higher level language/behaviour description...).

The (MAF) Finder and the RegionManager utility

A finder is an instance of class org.objectweb.mobilitools.smi.Finder, which implements MAF's MAFFinder interface. A finder is in charge of registering every agency and agent in a given region, for which it provides a central directory service.

It is not mandatory to use a finder, but some features rely on it however:

A finder for regionA must be launched before any agency in this region. It is automatically detected by agencies through the CORBA naming service, by resolving name "MAF/regionA/finder".

When using a MAF Finder, the RegionManager utility offers a wide range of agent and agent system distributed management (creation, termination, lookup...).

Mobile Object/Agent management

Creation and management of agents can be done through: Package org.objectweb.mobilitools.smi.goodies offers GUIs for agencies (see class AgencyGUI) and finders (see class FinderGUI), to easily view and manage agents and agencies, as well as the RegionManager helper class that encapsulates MAF operations into easy-to-use extended management methods.

Mobile object/Agent lifecycle

Here we explain the relationship between Agency's methods for agent management and MobileObject callbacks.
Agency method MobileObject callback(s) AgencyPersonality callback(s)
createLocalAgent afterBirth
resumeLocalAgent beforeResume
suspendLocalAgent beforeSuspend
moveLocalAgent beforeMove, afterMove, afterMoveFailed
terminateLocalAgent beforeDeath
terminate beforeShutdown, beforeDeath beforeShutdown, beforeDeath, agencyShutdown

Agent creation

Agent activity

It is up to the programmer to manage any kind of activity, following this specification:

Agent mobility

Agent termination

Agency termination

Communication issues

Every remote communication in SMI is based on CORBA. As far as agents are concerned, no communication tool or model is enforced. When agents are located in the same agency, they may use Java local method invocation, at least because the idea of "remote programming" is one of the important reason for mobility. However, it must be understood that some conflicts between communication and migration are likely to occur: what happens when an agent is moved while it is involved in communication (invoking or being invoked) is under the agent's responsibility. For instance, it is possible that an invocation terminates on a ghost copy of an agent, while the originally called agent has been moved, thus resulting in inconsistency. This problem is typically complex with RPC/RMI remote communication such as CORBA or Java-RMI, since uncontroled threads are created in agents when receiving remote invocations. A message-based communication infrastructure (like FIPA's) is easier to safely handle.

Class loading issues

At creation time, an agent is given a codebase, which is used to find its classes and resources. It will never change during the lifetime of the agent. The format and the interpretation of this codebase depends on the actual class loader used. By default, the SMIClassLoader is used, but other class loaders may be specified (URL, RMI or custom class loaders) through a class loader factory.

default class loader: SMIClassLoader

The codebase may be a local filesystem path or a URL, designating a directory or a Jar file holding the classes.

Classes and resources loaded with this codebase are stored in a dedicated cache. There is one cache associated to each codebase. A cache is cleared at garbage collection time if and only if no local agent is associated to the cache's codebase any more.

Each agent has its own class loader object (instance of class SMIClassLoader), which makes it possible to have agents of different classes with the same fully qualified name but associated to different codebases, in the same agency without any confusion. Whenever possible, classes are loaded using Java's standard classpath-based mechanism.

As a consequence of the combination of having one class loader object per agent, with this class cache management, agents may get reference on, and invoke, each other if and only if they have the same codebase (or they can be loaded by the system class loader from the classpath).

When an agent moves from agency A to agency B, agency B gets the missing classes with the following policy:

  1. B tries to get the undefined class from a local cache associated to the agent's codebase;
  2. if the undefined class is not present in cache, then it is downloaded from A's cache and put in the local cache associated to the agent's codebase (using fetch_class() operation on A's MAFAgentSystem CORBA interface);
  3. if A is unreachable or the class is not present in its cache, then the codebase is locally interpreted by B to load the class, and the loaded class is put in the local cache.
This policy also applies to resource loading (see SMIClassLoader.getResource()).
Step 1 and step 3 also apply to class and resource loading at creation time (step 2 being not applicable).

Note. This approach makes it possible to shutdown an agency as soon as its agents have been moved somewhere else, and it prevents from having a centralized class provider, which are interesting features regarding mobile computing. However, in order to fully enable these features, an agent should take care of getting at each move every possible class and resource it is likely to need during its lifetime.

using another class loader

One may need to use another class loader, to implement other class/resource download/isolation/caching policies/features, or to cope with specific constraints...
Implementing a custom class loader
Any sub-class of java.lang.ClassLoader may be used as class loader, but it should be the same in every agency (i.e. mixing various class loaders may not work unless they have been designed to).
A factory class must be provided, offering a static public method returning the custom class loader instances:
static public ClassLoader getClassLoader(java.lang.ClassLoader parent, java.lang.String codebase, org.omg.CfMAF.AgentProfile profile, org.omg.CfMAF.MAFAgentSystem provider)
this method is called for each agent creation and for each arriving agent to manage class loading.
Predefined class loaders
Below SMIClassLoader, SMI comes with two predefined class loader factories, respectively giving access to Java's URL class loaders and RMI class loaders:
org.objectweb.mobilitools.smi.lib.URLClassLoaderAdapter
org.objectweb.mobilitools.smi.lib.RMIClassLoaderAdapter - applies when agents use RMI.
Configuring SMI to use a predefined or custom class loader factory
set system property org.objectweb.mobilitools.smi.classloader to the factory's fully qualified class name.

Name service federation (suggestion for scalability)

A federation of CORBA name services may be used to avoid a centralized bottleneck. The most straightforward idea is to federate naming services at region level, i.e. having a "MAF" context in every naming service of the system, and to bind cross-references for every region name.

The NSbrowser and the NSbinder utilities in package org.objectweb.mobilitools.util.corba help this optional administration task.

Example

Here we describe the example of SmiTest class provided in the example directory. Note that this test class requires input in the terminal window from where the agency is run.

When running the JVM with command "java", it is very likely that some arguments or properties need to be set in order to configure the CORBA support:

Scripts in bin/ directory handle these issues.

Run a CORBA naming service

Depends on the ORB actually used; script COSnaming.sh in bin/ directory may help - see the installation section for details.

Run a Finder for the region (optional)

This step is not mandatory. Using a finder enables agent and agency management and lookup facilities through regions.

Besides MAFfinder.sh script in bin/ directory, there are 3 ways of launching a finder for region "regionA":

1. directly run the org.objectweb.mobilitools.smi.Finder class:
java org.objectweb.mobilitools.smi.api.Agency regionA
The finder is used through its MAFFinder CORBA interface only.
2. create an instance of org.objectweb.mobilitools.smi.Finder in a Java programme:
org.objectweb.mobilitools.smi.Finder my_finder = new org.objectweb.mobilitools.smi.Finder("regionA");
Then, a GUI may be attached to this finder with the following programme line:
org.objectweb.mobilitools.smi.goodies.FinderGUI my_gui = new org.objectweb.mobilitools.smi.goodies.FinderGUI(my_finder);
3. use the org.objectweb.mobilitools.smi.goodies.FinderGUI graphical finder:
java org.objectweb.mobilitools.smi.goodies.FinderGUI regionA

Create an agency

Besides agency.sh script in bin/ directory, there are 3 ways of launching an agency named "agency1" in region "regionA":
1. directly run the org.objectweb.mobilitools.smi.api.Agency class:
java org.objectweb.mobilitools.smi.api.Agency agency1 regionA
Then, this agency can be controled only through its MAFAgentSystem CORBA interface.
2. create an instance of org.objectweb.mobilitools.smi.api.Agency in a Java programme:
org.objectweb.mobilitools.smi.api.Agency my_agency = new org.objectweb.mobilitools.smi.api.Agency("agency1", "regionA");
Then, a GUI may be attached to this agency with the following programme line:
org.objectweb.mobilitools.smi.goodies.AgencyGUI my_gui = new org.objectweb.mobilitools.smi.goodies.AgencyGUI(my_agency);
3. use the org.objectweb.mobilitools.smi.goodies.AgencyGUI graphical agency:
java org.objectweb.mobilitools.smi.goodies.AgencyGUI agency1 regionA

Create an agent

In a Java programme:
org.objectweb.mobilitools.smi.api.AgentInfo info = my_agency.createLocalAgent("SmiTest", new Name("john's company", "john", org.objectweb.mobilitools.smi.api.Constants.TYPE_ID), "place1", "/smiHome/examples/", newProperties(), new String[0]);
If using an agency or finder GUI, click on "create" button and fill the fields (values: see parameters above).
Notes:
  1. Places are not managed by agencies. Any place name can be used without any place creation task.
  2. You may make the agent refuse the creation by answering 'n' in the terminal window.

Move an agent

Before moving an agent, you need to create another agency. Let's assume this agency has name "agency2" in the same region "regionA".
In a Java programme:
my_agency.moveLocalAgent(info.getAgent(), new Location("regionA", "agency2"), "place1");
From an agency or finder GUI, select the agent, click on "move" button, and fill the fields.
Notes:
  1. Any target place name may be chosen (places are not managed).
  2. You may make the agent refuse the migration, either before the move (in agency1) or after the move (in agency2) by answering 'n' in the terminal window attached to agency1 or agency2.

Suspend/Resume an agent activity

In a Java programme:
my_agency.suspendLocalAgent(info.getAgent());
my_agency.resumeLocalAgent(info.getAgent());
From an agency or finder GUI, select the agent, click on "suspend" or "resume" button.

Terminate an agent

In a Java programme:
my_agency.terminateLocalAgent(info.getAgent());
From an agency or finder GUI, select the agent, click on "terminate" button.

Terminate an agency

In a Java programme:
my_agency.terminate();
From an agency or finder GUI, click on "terminate" button.