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
).
org.objectweb.mobilitools.smi.api.AgencyPersonality
makes it possible for SMI kernel to invoke call-backs on the personality when agent or agency lifecycle events occur;
org.objectweb.mobilitools.smi.api.AgentSystem
is 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.
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:
org.objectweb.mobilitools.smi.goodies.RegionManager
.
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:
MAFAgentSystem
CORBA interface
org.objectweb.mobilitools.smi.MAFAgentSystem_impl
in the Javadoc section for details about what is really implemented)
createLocalAgent()
, terminateLocalAgent()
;
suspendLocalAgent()
, resumeLocalAgent()
;
moveLocalAgent()
;
listLocalAgents()
;
getAgentInfo()
, localAgentIsRunning()
;
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 |
Agency.createLocalAgent()
to create a new agent in current agency
MobileObject.afterBirth()
or 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
MobileObject.beforeResume()
or AgencyPersonality.beforeResume()
- may throw a BadOperation exception to deny activity resumption;
Agency.suspendLocalAgent()
to suspend an agent's activity
MobileObject.beforeSuspend()
or 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 beforeResume()
Agency.moveLocalAgent()
to move an agent
MobileObject.beforeMove()
or AgencyPersonality.beforeMove()
in current location, to let the agent prepare for migration - may throw a BadOperation exception to refuse the move;
MobileObject.afterMove()
or 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;
MobileObject.afterMove()
:
MobileObject.afterMoveFailed()
or AgencyPersonality.afterMoveFailed()
on agent in source location.
Agency.terminateLocalAgent()
to eliminate an agent
MobileObject.beforeDeath()
or AgencyPersonality.beforeDeath()
;
Agency.terminate()
to shutdown an agency
MobileObject.beforeShutdown()
or AgencyPersonality.beforeShutdown()
on every hosted agent;
AgencyPersonality.agencyShutdown
on agency.
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 main()
static method).
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 MAFAgentSystem
CORBA interface);
SMIClassLoader.getResource()
).
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.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).
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.URLClassLoaderAdapter
org.objectweb.mobilitools.smi.lib.RMIClassLoaderAdapter
- applies when agents use RMI.
org.objectweb.mobilitools.smi.classloader
to 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.
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:
COSnaming.sh
in bin/ directory may help - see the installation section for details.
Besides 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
MAFFinder
CORBA 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.sh
script 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
MAFAgentSystem
CORBA interface.
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[0]);
my_agency.moveLocalAgent(info.getAgent(), new Location("regionA", "agency2"), "place1");
my_agency.suspendLocalAgent(info.getAgent());
my_agency.resumeLocalAgent(info.getAgent());
my_agency.terminateLocalAgent(info.getAgent());
my_agency.terminate();