Mobile Code Toolkit v1.6.2
Created by: Tony
White
Note: In this document we refer extensively to mobile code. However,
the phrase mobile agent may also appear. The phrase mobile agent is generally
avoided as a result of the continuing debate over the definition and constitution
of a software agent.
Overview
This page is designed to give a mobile code toolkit user the minimum information
needed to get a system up and running. The following sections have been
defined:
Introduction
The mobile code toolkit v1.6.2 (MCT) introduces a number of important enhancements
in the areas of robustness and simplicity and brings the toolkit more into
alignment with the emerging Open Management
Group (OMG) Mobile Agent Facility (MAF) specification. It is not
intended that the MCT fully implement the MAF in that the proposed standard
is language neutral; our research interests focus on Java.
The MCT code is, unfortunately, not fully backwards compatible with
previous releases of the toolkit. However, strenuous efforts have been
made in order to ensure that as little pain as possible is required in
order to upgrade to v1.6.2.
The MCT provides several facilities:
-
bytecode transport, including optional state serialization;
-
a location service in order that pieces of mobile code can be found;
-
asynchronous and synchronous inter-mobile code messaging.
-
management of running mobile code.
Several examples, found in the mct.examples package, are included with
the toolkit which demonstrate:
-
basic code migration and mobility;
-
daemon behavioural extensibility;
-
mobile code state serialization;
-
passing startup state to mobile code;
-
inter-agent communication;
-
a simple blackboard application.
Important information
Identification of Agents
All mobile agents now have an identifier (mct.users.MCIdentifier) consisting
of three components. It is intended that the mobile agents have a unique
name within the network within which they are travelling. The identifier
components are:
-
name; e.g. Barney
-
authority; e.g. PUBLIC
-
class; e.g. mct.examples.MyNetlet.
The above example, when displayed as a java.lang.String, appears as: "Barney[PUBLIC]@mct.examples.myNetlet".
Each component of an identifier has a purpose. The name is for user indentification;
a null default is provided. The authority is for code sharing; a default
value of PUBLIC is assumed. When a mobile agent makes a migration request,
the destination is contacted and the authority of the agent used to locate
a class loader which may already cache the byte codes constituting the
class of the mobile agent. If the byte codes are already present, code
need not be transferred from the requesting location, thereby reducing
the consumption of network bandwidth. However, if the byte codes are not
present, the requesting location transfers them to the destination class
loader. All code necessary to start the mobile agent at the destination
will be transferred on demand. The migration of a piece of mobile code
will be considered successful when the onInit(java.util.Properties) method
of the mobile agent has returned true. If the class cannot be found, transferred,
created or deserialization of the mobile agent cannot be performed, migration
is considered to have failed and the onFailMigrate(java.net.InetAddress,
int, boolean) is invoked for the mobile agent, thereby allowing an alternate
migration decision to be made. If the migration is successful, the local
copy of the mobile agent is destroyed.
Code Transfer
Code transfer is now performed by classes implementing the mct.admin.MigrationInterface,
an interface which extends java.rmi.Remote. The Code Transfer Protocol
(CTP) used in previous versions of the toolkit has now been deprecated
in favour of a Remote Method Invocation (RMI) solution that is rapidly
becoming the norm within Java circles. Two classes implementing the mct.admin.MigrationInterface
have been written:
-
mct.admin.RemoteMigrationFacilitator,
-
mct.clients.InjectMobileCodeFacilitator.
The mct.admin.RemoteMigrationFacilitator (RMF) is installed as part of
the services provided by the RMI netlet daemon (mct.RMINetletDaemon). The
RMF encapsulates the protocol for transfer of class definitions (bytecodes,
mobile agent state and system information from one netlet daemon to another.
The mct.clients.InjectMobileCodeFacilitator class (IMCF) is used as part
of a client (mct.clients.WinMCTRMIClient) that interacts with an RMI netlet
daemon for the purpose of injecting mobile agents into the running network.
The IMCF cannot receive mobile code.
The WinMCTRMIClient
The WinMCTClient has been deprecated. The mct.clients.WinMCTRMIClient
provides a convenient mechanism for injecting code into a running mobile
code daemon. The interface is shown above and consists of five data entry
fields:
-
a mobile code name; e.g. Barney. The
text here is up to you. It can be any string of letters and numbers and
can contain embedded spaces. Starting and ending spaces will be trimmed.
-
a class name; e.g. mct.examples.MyNetlet.
The text here should be the fully qualified class name for the piece of
mobile code that you wish to inject into a running mobile code daemon.
Note: the CLASSPATH environment variable will be used to search for the
class or java archive (jar) file. If a class or jar file cannot be found
within the local file system it will not be possible to inject the mobile
agent into the running mobile code daemon. If a jar file cannot be located
but a class file can, a jar will be automatically created when the user
presses the Inject button.
-
an authority; e.g. PUBLIC. PUBLIC is the default
authority and is always created. The text here is up to you and should
reflect the sharing of code by mobile agents that you want to observe in
your running system. It can be any string of letters and numbers and can
contain embedded spaces. Starting and ending spaces will be trimmed.
-
a URL; e.g. //tony-pc/MF[PUBLIC]@mct.admin.RemoteMigrationFacilitator.
The text here should constitute the host and mobile code identifier of
a piece of mobile code that implements the mct.admin.MigrationInterface.
When no host information is provided, the name of the local machine will
be assumed; e.g. localhost. Should the destination RMF not exist, it will
not be possible to inject the mobile code to the running mobile code daemon.
-
a properties file; e.g. c:/barney/properties.prop.
The properties file is an ASCII file containing variable=value statements,
comment and blank lines that can be parsed by the java.util.Properties
load method. Mobile agent properties are intended to be passed, unchanged,
from one machine to another and should be thought of as the arguments given
to a program when executing it from the command line. The properties file
should exist, be readable, and contain information that can be used by
the mobile agent. The properties object created by parsing this file will
be passed to the mobile agent via the onInit(java.util.Properties) method
call. Should the file not exist or be unreadable, it will not be possible
to inject the mobile code to a running mobile code daemon.
A list of mobile agent definitions is also
provided. In this way, previously injected mobile code can be re-injected,
or copies created for the execution of duplicate tasks. Each entry in the
list has the format:
The "with: Properties" portion of an entry
will only be present if a properties file has been associated with the
mobile code entry. Selecting an entry in this list causes the MobileCodeName,
Authority,
ClassName,
URL,
and Properties fields to be updated
with the selected values.
Four action buttons are defined. These are:
-
Inject. The inject button causes the mobile
code defined by the MobileCodeName,
Authority,
ClassName,
URL,
and Properties fields to be injected to
the target mobile code daemon as specified in the URL.
If the RMF cannot be located at the specified
host, or is not an instance of a mct.admin.MigrationInterface, the mobile
code injection will fail. Note: an entry in the list
of mobile agent definitions need not be created before code injection
can occur. However, it is recommended that the definition be saved to the
list by pressing the add button before injecting
it.
-
Add. The add button causes the mobile code defined
by the MobileCodeName,
Authority,
ClassName,
URL,
and Properties fields to be added
to the list of mobile agent definitions.
An entry will only be added to the list if all of the fields for MobileCodeName,
Authority,
ClassName,
URL,
have
non-zero length and the Properties file
can be read. If the Properties file cannot
be read a dialog is displayed indicating the nature of the exception.
-
Delete. The delete button causes the currently
selected entry in the list of mobile agent definitions
to be deleted. If no entry is selected, a warning dialog is displayed.
Once deleted, the MobileCodeName,
Authority,
ClassName,
URL,
and Properties fields return to their
default values.
-
Destroy. The destroy button can be used to
destroy a mobile agent which is running on a mobile code daemon. In this
case, the URL field must point at an instance of
mct.management.ManagementInterface.
An example of the error dialog is shown below. It should be noted that
the error dialog is modal, interaction with the client can only continue
once the dialog has been acknowledged by pressing the OK button.
Mobile Code Management
With version 1.6.2, it is now possible to manage the mobile code running
within a mobile code daemon remotely. This is achieved through the mct.management.ManagementInterface.
The class mct.management.RemoteManager has been provided in order to start,
stop, destroy, suspend and resume a mobile agent. The WinMCTRMIClient
interface provides the ability to destroy mobile code using the destroy
button. Remote management of mobile agents can be achieved by either injecting
an instance of the class mct.management.RemoteManager to a running mobile
code daemon or by including it in the properties file associated with the
startup of a mobile daemon.
Mobile Code Daemon Properties
When a mobile code daemon (mct.RMIMobileCodeDaemon) starts, a properties
file must be provided for it. This file contains statements of the
form "variable = value", comments and blank lines and it is intended that
it be parsed by the load(java.io.InputStream) method of the java.util.Properties
class. Variables which are unknown to the mobile code daemon are ignored.
The statements between the horizontal lines of this section provide annotated
examples for a netlet daemon properties file. In the example file displayed,
all variables begin with the text netletdaemon. and all statements
are indicated in bold; e.g. netletdaemon.id = ND001.
Useful sections are:
The ordering of sections is unimportant as the properties file is parsed
completely before actual loading.
# Specify the netlet daemon id. The id
is typically the device's serial number, which is unique. [Return
to Sections]
netletdaemon.id=ND0001
# Set up console. If true, output will be
written to System.out. If false, no output will be generated and the mobile
# code daemon will be 'silent'. The .display.X, X=errors, warnings,
messages, debug, information or application
# statements allow a user to switch on/off ouput from the appropriate
mct.Console.Y, Y=error, warning, message, debug,
# information or applications methods. A true logging facility will
be added at some later release.
# [Return to Sections]
netletdaemon.console=true
netletdaemon.console.display.errors=true
netletdaemon.console.display.warnings=false
netletdaemon.console.display.messages=false
netletdaemon.console.display.debug=false
netletdaemon.console.display.information=false
netletdaemon.console.display.application=false
# Listening ports. These are only important
for the code transfer protocol. They are supported for reasons of
# backward compatibility. These lines can be removed without danger;
the defaults will be used. If the rmi protocol
# is used for mobile code transport, these statements will be ignored
and the daemon will NOT listen for messages
# on these ports. [Return to Sections]
netletdaemon.listen.tcp.port=3100
netletdaemon.listen.udp.port=3200
# Default mobile code migration. Host names
and ports are provided for both TCP and UDP transport and the
# default transport protocol defined. These statements are only important
for the code transfer protocol which
# is deprecated. They are supported for reasons of backward compatibility.
These lines can be removed without
# danger; the defaults will be used. [Return
to Sections]
netletdaemon.default.migration.tcp.ip=localhost
netletdaemon.default.migration.tcp.port=3300
netletdaemon.default.migration.udp.ip=localhost
netletdaemon.default.migration.udp.port=3400
# The default protocol specifies whether tcp, udp or rmi will be used
for transporting of mobile code from
# one mobile code daemon to another. In this release of the software,
this should be set to rmi.
netletdaemon.default.protocol=rmi
# Set up the Communication
Facilitator. The Communication Facilitator provides inter-agent messaging
services.
# If enabled, local inter-agent messaging will be supported. If a mediator
is present in the system, region-wide
# messaging will be supported. The .mobilecode variable specifies the
identifier
of the communicator facilitator.
# The .properties variable specifies the name of the file within the
local file system that contains "variable=value"
# statements, comments and blank lines that can be parsed by the load(java.io.InputStream)
method of the
# java.util.Properties class. The properties associated with the Communication
Facilitator are described here.
# Note that it is possible to implement your own Communication Facilitator,
# mct.mediator.CommunicationFacilitatorInterface
must then be implemented for the users' class.
# [Return to Sections]
#
netletdaemon.facilitator.enable=true
netletdaemon.facilitator.mobilecode=F1@mct.mediator.CommunicationFacilitator
netletdaemon.facilitator.properties=/mct/configuration/fac1.prop
#
# Set up the Migration Facilitator.
The .enable variable states whether migration is enabled or not. If true,
migration is
# supported. Otherwise, it is not. The .mobilecode variable defines
the identifier of the migration facilitator.
In this
# release of the software, a single migration facilitator is supported.
The .properties variable specifies the name of the
# file within the local file system that contains "variable=value"
statements, comments and blank lines that can be parsed
# by the load(java.io.InputStream) method of the java.util.Properties
class. The properties associated with the
# Migration Facilitator are described here. Note that it is possible
to implement your own
# Migration Facilitator, the mct.admin.MigrationInterface
must then be implemented for the users' class.
# [Return to Sections]
#
netletdaemon.migrator.enable=true
netletdaemon.migrator.mobilecode=MF1@mct.admin.RemoteMigrationFacilitator
netletdaemon.migrator.properties=/mct/configuration/mig1.prop
#
# Install mobile code that
is located in the classpath. This section contains variables starting with
the text
# netletdaemon.install.mobilecode. The index; e.g. 0, 1 or 2
is used to associate properties and jar
files with individual
# pieces of mobile code. The value associated with a netletdaemon.install.mobilecode.x,
x=0,1,2... variable
# statement is the identifier
of a piece of mobile code. The value associated with a
# netletdaemon.install.mobilecode.properties x, x=0,1,2... variable
statement is the name of a file within the local
# file system containing properties for the mobile code to be started.
If the file cannot be accessed, the mobile code will
# not be started and will be ignored.
#
# NOTE: the indices associated with the
netletdaemon.install.mobilecode.x,
x=0,1,2.. statements must be
# consecutive. For
example, using x=0,1,3,4,5 will result in the statements for x=3,4 and
5 being ignored.
#
# [Return to Sections]
#
netletdaemon.install.mobilecode.0=blackboard@mct.blackboard.MsgBlackBoard
netletdaemon.install.mobilecode.properties.0=/mct/examples/messaging/bb.prop
netletdaemon.install.mobilecode.1=NN1@mct.examples.messaging.NotifyNetlet
netletdaemon.install.mobilecode.2=EQ1@mct.examples.messaging.EnquireNetlet
#
# Install mobile code jar files
that are located on the classpath. This section contains variables starting
with the text
# netletdaemon.install.mobilecode.jar The index; e.g. 0, 1 or
2 is used to associate jar files with individual
# pieces of mobile code. The index used must correspond to the index
used in the mobile code startup
section.
# The value associated with a netletdaemon.install.mobilecode.jar.x.y,
x=0,1,2...; y=0,1,... variable is the name of a java
# archive (jar) within the local file system containing compressed
byte codes for the mobile agent. The classpath will
# be searched for the jar file. If the file cannot be accessed, the
mobile code will not be started and will be ignored.
# It is possible to associate several jar files with a single mobile
agent
#
# NOTE: the indices associated with the
netletdaemon.install.mobilecode.jar.x.y,
x=0,1,2...; y=0,1,... statements
# must be consecutive
in both x and y. For example, using x=0,1,3,4,5 will result in the statements
for x=3,4 and 5
# being ignored.
Similarly, using y=0,1,3 will result in statements for y=3 being ignored.
#
# [Return to Sections]
#
netletdaemon.install.mobilecode.jar.1=NN1@mct.examples.messaging.NotifyNetlet
netletdaemon.install.mobilecode.jar.1.0=/mct/examples/messaging/NotifyNetlet.jar
netletdaemon.install.mobilecode.jar.2=EQ1@mct.examples.messaging.EnquireNetlet
netletdaemon.install.mobilecode.jar.2.0=/mct/examples/messaging/EnquireNetlet.jar
#
# Set up RMI migration parameters.
Several migration destinations can be specified by using .1, .2 etc. It
is not necessary
# to specify the host each time, the previous host will be assumed;
i.e. in the example below, localhost will be assumed
# for the MF1@mct.admin.RemoteMigrationFacilitator. Also, the default
migration is the last migration host/name pair
# defined. In the example below, that would be //localhost/MF1[PUBLIC]@mct.admin.RemoteMigrationFacilitator.
# Providing several default migration destinations ensures that a piece
of mobile code can move within a network that
# is unreliable. The set of available migration destinations known
to the mobile code daemon can be obtained using the
# getMigrationDestinations() call; an array of URLs is returned.
#
# NOTE: the indices associated with the
netletdaemon.migration.rmi.<var>.x,
x=0,1,2.., var={host,name}
# statements must
be consecutive. For example, using x=0,1,3,4,5 will result in the statements
for x=3,4 and 5
# being ignored.
#
# [Return to Sections]
#
netletdaemon.migration.rmi.host.0=localhost
netletdaemon.migration.rmi.name.0=MF2@mct.admin.RemoteMigrationFacilitator
netletdaemon.migration.rmi.name.1=MF1@mct.admin.RemoteMigrationFacilitator
#
# Security. All statements in this section
start with the text netletdaemon.security. If the enable variable
is true,
# security will be enabled for the netlet daemon, otherwise security
will be completely disabled and all other
# netletdaemon.security. variables will be ignored. We currently
highly
recommend that security remain disabled as
# we are currently re-evaluating the security design. If the .enable.MCDSecurityManager
variable is true, the system
# security manager will be set to an instance of mct.security.MCDSecurityManager.
The .url.key.database statement
# is used to point the system at a database of public keys that can
be used to authenticate mobile code. These keys
# are used to ensure that signed code has not been tampered with during
transport. A "super user" is provided in
# the .root variable. The netletdaemon.security.user.allows.access.<var>.x,
x=0,1,2...; var={mobilecodemanager,
# storagemanager} is used to restrict access to the mobile code
and storage managers (as provided by the
# mct.users.MCDInterface). All users must be enumerated, no
wildcarding or UNIX-like group facility is
# currently supported.
#
# NOTE: the indices associated with the
netletdaemon.security.user.allows.access.<var>.x,
x=0,1,2...;
# var={mobilecodemanager, storagemanager} statements
must be consecutive. For example, using x=0,1,3,4,5
# will result in
the statements for x=3,4 and 5 being ignored.
#
# [Return to Sections]
#
netletdaemon.security.enable=false
netletdaemon.security.enable.MCDSecurityManager=false
netletdaemon.security.url.key.database=url
netletdaemon.security.root=Admin
netletdaemon.security.user.allows.access.mobilecodemanager.0=Admin
netletdaemon.security.user.allows.access.storagemanager.0=Admin
Communication Facilitator
The Communication Facilitator (CF) provides local inter-agent communication.
The CF delivers messages sent by mobile agents and manages the mailboxes
associated with locally-resident agents. Together with the mediator,
region-wide inter-agent communication is supported. The CF must
be setup within the properties
file used to start the mobile code daemon. Currently, a single CF can be
running with a mobile code daemon. The CF has properties associated with
it. They are described below:
# The name of the piece of code that will implement the local directory
of agents. Unless the user is going to implement
# their own directory of mobile agents, the mct.mediator.LocalMCDirectory
should be used. The text LMCD1 is of
# user interest only and should be chosen to reflect a mobile agent
naming scheme meaningful to the user.
fac.directory.mobilecode=LMCD1@mct.mediator.LocalMCDirectory
# The properties associated with the local directory. Currently, these
properties control the display of a
# window containing the names of the mobile agents residing within
the mobile code daemon and the title
# of the window. The properties file contains configuration information
for the local directory. See here
for details.
fac.directory.properties=/mct/examples/messaging/dir.prop
# The port used for communication with this communication facilitator.
The default provided is 6666.
fac.port=6666
# This used to be the mediator port. However, it is now deprecated
as the communication with the Mediator is via RMI.
# This port is ignored; the statement is deprecated.
fac.mediator.port=8888
# The IP where the mediator is to be found. It is the host name where
the regional mediator is running.
fac.mediator.ip=localhost
# The RMI name of the mediator on the remote host. The default value
is "Mediator"
fac.mediator.name=Mediator
# The facilitator needs to install a listener for events that pertain
to the movement of mobile agents. Unless the user is going
# to implement their own listener, the mct.mediator.RemoteMediatorListener
should be used. The text RML1 is of
# user interest only and should be chosen to reflect a mobile agent
naming scheme meaningful to the user.
fac.mediator.listener=RML1@mct.mediator.RemoteMediatorListener
# The .mediator.listener.properties variable allows the user to specify
properties for the remote mediator listener. There is
# no default for this variable. It is largely unnecessary as the .mediator.name
and .mediator.ip override the values contained
# in this file.
fac.mediator.listener.properties=listener.props
Mediator
The Mediator provides a mobile agent location service and supports region-wide
inter-agent communication through interaction with Communication
Facilitators. A Mediator must support the mct.mediator.RemoteMediator
interface. The current implementation is provided by the mct.mediator.RemoteMediator
class. Interaction with this implementation of a mediator is via RMI. The
Mediator is started using the command line statement:
java mct.mediator.RemoteMediator <properties-file>
wherre <properties-file> is the name of a file within the local file
system that contains "variable=value" statements that can be parsed using
the load(java.io.InputStream) method of the java.util.Properties class.
The statements supported are shown below:
# The .rmi.name variable specifies the name used for binding the mediator
within the RMI registry. The
# default value is "Mediator"
directory.rmi.name=Mediator
# The .display.name variable specifies the title of the window displaying
the locations of mobile code (if present).
# The default value is "Remote Mobile Code Directory". This variable
is relevant only if the .display.enable variable
# is true.
directory.display.name=Remote Mobile Code Directory
# The .display.enable variable determines whether a window displaying
the locations of mobile code will be displayed.
# The default value is false.
directory.display.enable=false
# The .display.content variable determines whether summary information
only; i.e. the current local of regional mobile
# agents is displayed or whether all mobile agent movements are reported.
By default, a summary window is presented.
# This variable is relevant only if the .display.enable variable is
true.
directory.display.content=summary
# The .security variable specifies the class of security manager to
be installed. There is no default for this variable; i.e. no
# security manager will be installed.
directory.security=mct.security.MCDNullSecurityManager
Mobile Code Directories
The Communicator Facilitator and Mediator use a mobile code directory for
storing mobile code location and other information. These directories are
installed as part of the code running within a mobile code daemon. As such,
they can be initialized with java.util.Properties. These properties are
stored in ASCII files and parsed using the java.util.Properties load(java.io.InputStream)
method. The properties than can be initialized are:
Variables defined for Mobile Code Directories
directory.display.enable |
true/false, default is false |
directory.display.content |
summary/all, default is summary |
directory.display.name |
any String, no default |