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.AgencyPersonalitymakes it possible for SMI kernel to invoke call-backs on the personality when agent or agency lifecycle events occur;
org.objectweb.mobilitools.smi.api.AgentSystemis an empty interface representing the interface given by the personality to the hosted agents, that we call the shell. The methods finally made available to the agents through this shell are personality-specific.
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
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
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:
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:
org.objectweb.mobilitools.smi.MAFAgentSystem_implin the Javadoc section for details about what is really implemented)
org.objectweb.mobilitools.smi.goodiesoffers GUIs for agencies (see class
AgencyGUI) and finders (see class
FinderGUI), to easily view and manage agents and agencies, as well as the
RegionManagerhelper 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)|
|moveLocalAgent||beforeMove, afterMove, afterMoveFailed|
|terminate||beforeShutdown, beforeDeath||beforeShutdown, beforeDeath, agencyShutdown|
Agency.createLocalAgent()to create a new agent in current agency
AgencyPersonality.afterBirth()to give the agent a reference to the hosting agency, and to make the agent initialize itself with arguments - may throw a BadOperation exception to abort agent creation. This callback is supposed to start the agent activity, since the agent will be considered as active when created.
Agency.resumeLocalAgent()to resume an agent's activity
AgencyPersonality.beforeResume()- may throw a BadOperation exception to deny activity resumption;
Agency.suspendLocalAgent()to suspend an agent's activity
AgencyPersonality.beforeSuspend()- may throw a BadOperation exception to deny activity suspension;
afterBirth()is supposed to start the agent activity, probably in a similar way as
Agency.moveLocalAgent()to move an agent
AgencyPersonality.beforeMove()in current location, to let the agent prepare for migration - may throw a BadOperation exception to refuse the move;
AgencyPersonality.afterMove()on the remote agent copy, to give it a reference to the new hosting agency, and to make it settle in the new location - may throw a BadOperation exception to refuse the reinstallation;
AgencyPersonality.afterMoveFailed()on agent in source location.
Agency.terminateLocalAgent()to eliminate an agent
Agency.terminate()to shutdown an agency
AgencyPersonality.beforeShutdown()on every hosted agent;
Constants.agencyIsClosed). The agency waits for currently running invocations to be finished before actually terminating. Finally, the agency process may exit after a standard or specified delay if it is running as standalone (i.e. using the agency's
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.
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:
fetch_class()operation on A's
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.
java.lang.ClassLoadermay 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).
static public ClassLoader getClassLoader(java.lang.ClassLoader parent, java.lang.String codebase, org.omg.CfMAF.AgentProfile profile, org.omg.CfMAF.MAFAgentSystem provider)
org.objectweb.mobilitools.smi.lib.RMIClassLoaderAdapter- applies when agents use RMI.
org.objectweb.mobilitools.smi.classloaderto the factory's fully qualified class name.
The NSbrowser and the NSbinder utilities in package
org.objectweb.mobilitools.util.corba help this optional administration task.
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:
COSnaming.shin bin/ directory may help - see the installation section for details.
MAFfinder.sh script in bin/ directory, there are 3 ways of launching a finder for region "regionA":
java org.objectweb.mobilitools.smi.api.Agency regionA
MAFFinderCORBA interface only.
org.objectweb.mobilitools.smi.Finder my_finder = new org.objectweb.mobilitools.smi.Finder("regionA");
org.objectweb.mobilitools.smi.goodies.FinderGUI my_gui = new org.objectweb.mobilitools.smi.goodies.FinderGUI(my_finder);
java org.objectweb.mobilitools.smi.goodies.FinderGUI regionA
agency.shscript in bin/ directory, there are 3 ways of launching an agency named "agency1" in region "regionA":
java org.objectweb.mobilitools.smi.api.Agency agency1 regionA
org.objectweb.mobilitools.smi.api.Agency my_agency = new org.objectweb.mobilitools.smi.api.Agency("agency1", "regionA");
org.objectweb.mobilitools.smi.goodies.AgencyGUI my_gui = new org.objectweb.mobilitools.smi.goodies.AgencyGUI(my_agency);
java org.objectweb.mobilitools.smi.goodies.AgencyGUI agency1 regionA
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);
my_agency.moveLocalAgent(info.getAgent(), new Location("regionA", "agency2"), "place1");