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:

  1. bytecode transport, including optional state serialization;
  2. a location service in order that pieces of mobile code can be found;
  3. asynchronous and synchronous inter-mobile code messaging.
  4. management of running mobile code.
Several examples, found in the mct.examples package, are included with the toolkit which demonstrate:
  1. basic code migration and mobility;
  2. daemon behavioural extensibility;
  3. mobile code state serialization;
  4. passing startup state to mobile code;
  5. inter-agent communication;
  6. 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:
  1. name; e.g. Barney
  2. authority; e.g. PUBLIC
  3. 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:
  1. mct.admin.RemoteMigrationFacilitator,
  2. 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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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:

  1. 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.
  2. 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.
  3. 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.
  4. 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 thenetletdaemon.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 thenetletdaemon.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 thenetletdaemon.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 thenetletdaemon.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