FAQ


Frequently Asked Questions

The FAQ provides general information about developing using the ADK software. It also includes the latest troubleshooting tips on ADK development.

AGENT CREATION AND SPECIFICATION

  • What are some typical tasks an agent might perform?
  • My agent needs to wait for the outcome of a lengthy or blocking procedure before proceeding. Is this possible and how do I specify the details?

AGENT COMMUNICATION AND MESSAGING

  • How do the agents collaborate?
  • How will I know that a message is a reply to my question?
  • Which protocol/ standard does the ADK use to implement messaging?
  • Does ADK messaging offer guaranteed delivery? How?
  • Can the messaging system of the ADK be connected to Sun’s JMS standard?
  • What support is there in the ADK for transactions (commit, rollback)? Is it XA-compliant?

AGENT MOBILITY

  • How do the agents decide where and/or when to move?
  • How do the agents migrate?

AGENT BEHAVIOUR AND CONTROL

  • How do you control mobile agents? (for example, kill, suspend, retask, etc.)
  • How would an agent carry files?
  • What objects can agents carry in a message?
  • How do I share data between tasks?

SECURITY

  • What security features are built into the system?
  • How do agents handle firewalls?
  • Is it possible to create your own keystore.dat from scratch? What about role.properties? DNA files and certificates?
  • What are keystores 1,2,3,4 used for?
  • How can I modify the keystores provided? (password “testtest” does not work in keystore)
  • Why would anyone want to add a HabitatID in the keytool?

INTERFACING WITH OTHER APPLICATIONS

  • How can I connect to the outside world?
  • How do external applications interact with the agents? (i.e. message passing, native calls, etc…)

WEB SERVICES

  • How can my agent use Web Services? How do I do this using the agent Template?

PERSISTENCE

  • What is persistence and why is it necessary?
  • Are agents persistent over time? Which databases are currently supported?
  • How do agents implement persistence?
  • How do I connect to databases to implement persistence?

PERFORMANCE

  • What’s the size of the agent with a 4k data payload?
  • How many agents can run at one time? How much memory is typically used per agent? How much CPU time is used?
  • Can I make blocking calls in my agent?
  • Are there any documented benchmarks for mobile agents over various network bandwidths?

TROUBLE SHOOTING

  • All Error Messages
  • I am getting the following error message: ” Could not load tryllian/afc/agent/Agent “
  • When I start my habitat, a huge amount of XML starts pouring over my screen. Why is this happening and how can I prevent it?
  • My habitat tells me I’ve got a “corrupted jarcache”. What’s a jarcache, how does it become corrupted, and what can I do about it?

GENERAL QUESTIONS

  • How much coding is involved in creating an agent system?
  • How to debug agents using a source code debugger?

CONTACT TRYLLIAN

  • Help! I still have more questions!

AGENT CREATION AND SPECIFICATION

  • What are some typical tasks an agent might perform?

Typical tasks and applications of mobile agents include remote systems monitoring and management, distributed application integration (with agents wrapping the various applications or data sources), workflow automation, dynamic deployment of (native) code and components, and more.

  • My agent needs to wait for the outcome of a lengthy or blocking procedure before proceeding. Is this possible and how do I specify the details?

Yes and No. Let’s start with “No”.

A habitat is based on cooperative multitasking. All agents receive their events — heartbeats and messages — within a limited number of threads. It’s impossible to change that without hacking the Java virtual machine. You would not want to permanently assign every agent its own thread; this would severely limit the number of agents that a habitat can run. Therefore, it’s important that agents do not use up a lot of time during their heartbeats. A heartbeat is simply a slice of time, and an agent will have to relinquish control of itself. If an agent starts abusing its timeslice, performance of other agents will suffer.

Please note that from this point of view, a message is identical to a heartbeat; any message will give an agent the chance to perform an action. Misbehaving agents may not receive heartbeats, and in addition, their messages mayl also be held. The exact definition of “too long” and “abuse” is relative. If there is only one agent in a habitat, the agent can spend more time on itself.

However, there are legitimate reasons for an agent to perform a lengthy process. So there’s a “Yes” answer. In these cases, the agent CAN request a thread all of its own. It is important to stress that not all agents should do this, otherwise the Java virtual machine would run out of threads. Agents should also relinquish their thread as soon as possible. It’s very easy to start something in its own thread by using the ExecutionEnvironment.scheduleRoutine(Routine target) function. A Routine is a special Runnable that will be executed by the habitat as soon as a thread becomes available. When the Routine is done, the thread becomes available for other agents again.

More information on this topic can be found under the Performance section.

AGENT COMMUNICATION AND MESSAGING

  • How do the agents collaborate?

Agents use String-based messaging to communicate with each other; this is done both for security reasons and compatibility reasons. The AFC provides several components to make this easier, based on FIPA standards. Agents can find each other using a Naming Service that, in turn, uses the JNDI (javax.naming) interface.

  • How will I know that a message is a reply to my question?

Send a message through a conversation and set the task which is waiting for a reply, as a message handler for this conversation. Then, you will only receive messages that are replies to your original message. Here is a coding example:

class MyTask extends DefaultTask implements MessageHandler {

  private Conversation myConversation;

  protected void taskStarted() {

    // Create conversation
    myConversation = getAgentContext().createConversation(this);

    // Create message
    OutgoingMessage message = new Query(…);

    // Send message
    try {
      myConversation.send(message);
    }
    catch (NoSuchAgentException nsae) {
      fail(“Unable to send message”);
    }
  }

  public void handleMessage(IncomingMessage message) {

    // This message is a reply to our query….

  }

}

  • Which protocol/standard does the ADK use to implement messaging?

By default the ADK uses a HTTP based protocol to transfer messages between habitats. Thanks to a plugin messenger architecture and messaging gateway tasks, alternative protocols such as SOAP and JMS are or can become supported.

  • Does ADK messaging offer guaranteed delivery? How?

In the ADK, “guaranteed delivery” refers to the following: after sending a message, the sender will always be notified if the delivery has failed. Delivery fails if the system CANNOT deliver the message, for instance because the addressed agent does not exist. It is up to the sending agent to handle such situations adequately.

Agents can request to be stored in a database using persistence during a period of nonactivity to save memory and CPU usage. While an agent is in persistence, it is no longer actively present, but the runtime environment will “wake up” the agent to accept any messages that arrive for it. The transition of the agent from active to persisted has been re-engineered to ensure correct delivery of messages arriving at exactly that instant.

Starting with ADK release 2.1, guaranteed delivery also holds for remote messaging. As of release 3.0 a messenger plugin is available that allows JMS-compliant message queueing products like WebSphere MQ to be used instead of HTTPS.

In the case of local messaging, the delivery failure will be reported as a NoSuchAgentException. In the case of remote messaging, the sending agent will receive a message indicating the failure.

  • Can the messaging system of the ADK be connected to Sun’s JMS standard?

Yes, ADK 3.0 includes a messenger plugin for JMS. Alternatively there’s
a tryllian.afc.task.jms package that helps you to communicate with JMS.

Yes, the connection with JMS is quite simple and has been tried out. The ADK 3.0 includes a package that helps you to communicate with JMS. An example in the scenarios is using this package is also provided. The ADK also provides a JMS messenger plugin.

  • What support is there in the ADK for transactions (commit, rollback)? Is it XA-compliant?

There is no out-of-the-box support for (distributed) transaction management in the ADK. The agent metaphor, in combination with the FIPA agent conversation protocols used for messaging, offers a certain light form of agent transactions. Besides this, existing database technology can be used to commit mission critical data consistently into a database via JDBC. This has proven to be sufficient for the applications built with the ADK so far.

AGENT MOBILITY

  • How do the agents decide where and/or when to move?

This depends on the application. A typical application has a number of locations with specific roles (e.g. server machine, database machine etc.), but agents can also be dynamically directed to specific locations. Scenarios where agents form a peer-to-peer network or perform network discovery are also possible.

  • How do the agents migrate?

Agents offer themselves to the Transporter System Agent. The Transporter encodes the agent’s code and state into a set of messages and uses the transport layer to communicate with the Transporter at the destination.

Agent code is only transmitted when necessary (not if already present); code identity is based on several aspects, among which include a secure hashcode over the Jarfiles. This ensures an optimal transport time, without requiring the code to be present on the other side. Multiple versions of the same Java class can co-exist in a habitat, eliminating a number of version control issues.

AGENT BEHAVIOUR AND CONTROL

  • How do you control mobile agents? (for example, kill, suspend, retask, etc.)

One can kill them, given sufficient permissions. Suspend and (re)scheduling options cannot yet be applied “from the outside”, but this functionality can be easily added within the application itself by letting the agents handling such requests themselves. For example, see the SNMP example. Furthermore, the security settings can be used for fine-grained control over the permissions of each agent.

  • How would an agent carry files?

The most flexible way of carrying a file (for example, an .EXE file) is by converting it to a serializable object and storing it as a property in the agent context.

  • What objects can agents carry in a message?

Regular messages use string fields only. To transmit other (serializable) objects, use a special ObjectMessage as found in tryllian.afc.message.object.

If the object is not serializable, you can implement a wrapper arround the object and let your wrapper implement a serializable, something like:

public class YourWrapper extends ResultSet implements Serializable

Another way to pass objects requires storing your object to a file and making it available through a URL. Then, you can pass this URL to the moving agent and access this URL from anywhere.

  • How do I share data between tasks?

The best way to do this is to store an object as a property in the AgentContext. You do this by calling getAgentContext().setProperty(key, value) from within a task. Every task can access your data by calling getAgentContext().getProperty(key).

SECURITY

  • What security features are built into the system?

Agents are authenticated and authorized at a class level, following the Java 2 Security Model. The identity of an agent is established based on the identity of the entity signing the agent’s classes. Signing agent’s classes is performed using a public-private key method. The algorithm used for this is DSA with SHA1, with key length of 512, 768 or 1024 bits.

The habitats (agent runtime environments) keep a list of known issuers (certification authorities) and signers to solve trust issues. We use standard X509 certificates; they can be issued by Tryllian or other parties.

The following additions were made to the Java Security Model:

  1. Permissions are grouped in sets, called “roles”. Roles can be assigned to identities, based on the owner or issuer of the certificate. Roles are granted by the habitat administrator. This allows you to group related entities into one permission set.
  2. Agents need explicit permissions to enter a habitat. Once in the habitat, agents need explicit permission to access system resources, e.g. to create threads, access files, or use network connections.
  3. Habitat communication is done using HTTP or HTTPS. When using HTTPS, only mutually authenticated habitats will communicate. By default, habitat authentication is done using DSA using a key length of 412, 768 or 1024 bits. Messages exchanged by the habitats are encrypted and their integrity is protected by a TLS based protocol/
  • How do agents handle firewalls?

Firewall can be tunneled using third-party products like stunnel. Additionally a habitat may be configured to use a http proxy.

  • Is it possible to create your own keystore.dat from scratch? What about role.properties? DNA files and certificates?

You can make your own keystore.dat file with the Keytool GUI application in the ADK distribution (bin\keytool.bat). This tool uses the JDK security API, which in turn depends upon a ‘provider’. The ADK uses iaik_ssl as security provider, see lib\runtime\iaik_jce.license.html for details.

Alternatively, you can use the default JDK security provider by creating your certificates with the CLI application “keytool” which is included with the JDK. The roles.properties file only uses the aliases from keystore.dat. All aliases in the keystore.dat should also be mentioned in roles.properties.


DNA Files and Certificates?

I created my DNA file and tried running it with a certificate I created but I am still getting an error. What did I do wrong?

The problem is probably the ADK_ROOT (classpath) set in the habit.bat/habitat.sh file. If the classes of your agent are reachable via this classpath the habitat will use those classes and not the signed ones from the dna file. The classes from the classpath are loaded using a default classloader which doesn’t have the correct permissions. This problem can be avoided by not putting “.” or any other reference to your classfiles in your classpath, this way you’ll be sure the classes will always be loaded from the DNA files.

Furthermore, it could also be the case that your alias is not in config\roles.prop. Please check that this is the case.

  • What are keystores 1,2,3,4 used for?

These are four certificates provided for testing and running the examples. Their grouping and passwords can be found in README-keystores.html. Also described in this readme are keystore-certs.dat (password “testtest”) and keystore.dat (password “developer1“). The keystore called habitat-private-keystore.dat (password 12345678) is used for making secure connections. Look in habitat.properties to find the related configuration lines.

  • How can I modify the keystores provided? (password “testtest” does not work in keystore)

keystore.dat has password developer1. You cannot modify a certificate once it has been signed. You can, however, add or remove aliases associated with the certificate, and import or export certificates to or from a keystore. Adding or removing aliases cannot be done using the ADK keytool GUI. You should use JDK\bin\keytool.exe to do this. Open a DOS box and type:

‘keytool -keyclone -alias OLD_ALIAS -dest NEW_ALIAS -keystore keystore.dat’ to add an alias to the keystore.
‘keytool -delete -alias OLD_ALIAS -keystore keystore.dat’ to remove an alias from the keystore.

Importing and exporting certificates to or from a keystore is possible using either tool.

  • Why would anyone want to add a HabitatID in the keytool?

HabitatID’s are used to identify habitats in case of remote messaging. If no HabitatID is specified in the keystore, one will be automatically generated. This mechanism can be used by the distributor of certificates to easily identify habitats that use the certificates.

INTERFACING WITH OTHER APPLICATIONS

  • How can I connect to the outside world?

Currently, ADK releases 1.3.9 and above support the Standalone Messenger. For more information, refer to the Developer’s Guide. Your agent can also use any Java library like JDBC, CORBA, JNDI. For some of them you’ll need to have access privileges and/or run the task in a separate thread.

  • How do external applications interact with the agents? (i.e. message passing, native calls, etc…)

There are several possibilities; the preferred one is communication through the Standalone Messenger (available, as of ADK release 1.3.9). The Messenger Component is a HTTPS based library that can be embedded in any Java application. Using this library, the application can send and receive messages to and from agents inside a habitat.

Another solution is writing a suitable messenger plugin.

From the agent’s point of view, everything is possible, as long as the agent has the correct permission. Examples include, but are not limited to: JNI (for example, used in hardware detection applications), JDBC (can be used to to manipulate different databases on different machines) and I/O using a pipe-like mechanism (used in an application where users interact with agents using SMS).

WEB SERVICES

  • How can my agent use Web Services? How do I do this using the agent Template?

To begin with, Tryllian is working on a web services messenger plugin.
Contact us for more information on this. The agent Template, by default, doesn’t contain the settings to compile and use Web Services tasks. Furthermore, the file webservices.jar is not signed. Thus, you may have problems if you try to create an agent that uses Web Services. Follow these steps to get your agent to use Web Services using the agent Template.

First you have to install Axis 1.0, see chapter 12 “Web Services Examples” of the scenarios document.

Modify build.properties by adding the following lines:

lib.axis=${lib.base}/webservices/axislibs
classpath.axis=${lib.axis}/axis.jar: ${lib.axis}/commons-logging.jar: ${lib.axis}/commons-discovery.jar:${lib.axis}/jaxrpc.jar: ${lib.axis}/log4j-1.2.4.jar:${lib.axis}/saaj.jar: ${lib.axis}/wsdl4j.jar: ${lib.base}/webservices/xerces/xercesImpl.jar: ${lib.base}/webservices/xerces/xmlParserAPIs.jar

NOTE: the libraries in the Axis package can vary between versions, please make sure all jar files in the axislibs directory are in the classpath.
classpath.ws=${classpath.axis}: ${lib.base}/webservices/webservices.jar: ${lib.base}/webservices/uddi/uddi4j.jar

Modify the build.xml file:

   <javac      srcdir=”${relative.source}”
           destdir=”${relative.compiled}”
           classpath=”${project.classpath}:${classpath.ws}”
           debug=”true”
           optimize=”false”
   />
Copy the config/dna.catalog to the template-project/config directory.

Change the file example.descriptor.xml with

      <shared-ref type=”stdlib” name=”webservices”/>
      <shared-ref type=”stdlib” name=”uddi”/>
      <shared-ref type=”stdlib” name=”axis”/>
      <shared-ref type=”stdlib” name=”jaxrpc”/>
      <shared-ref type=”stdlib” name=”saaj”/>
      <shared-ref type=”stdlib” name=”wsdl4j”/>
      <shared-ref type=”stdlib” name=”commons-logging”/>
      <shared-ref type=”stdlib” name=”commons-discovery”/>

Sign the webservices.jar file by adding the following to build.xml

      <!– Sign the webservices jar file as it should be –>
      <target name=”sign-ws” depends=”init”>
         <signjar jar=”../lib/webservices/webservices.jar”
            alias=”${jarsign.tryllian-developer}”
            storepass=”${jarsign.password}”
            keystore=”${jarsign.keystore}”
         />
      </target>

Execute command “build sign-ws”

Now, your agent will be able to use Web Services tasks.

PERSISTENCE

  • What is persistence and why is it useful?

The ADK offers database persistence to allow a running habitat/application to continue after it has been restarted. Agents reside on a network, and in the event that the network, and thus the habitat, goes down, the ADK provides persistence to prevent the agents from disappearing. The saving and restoring of agents is known as Agent Persistence, and is an important feature of the ADK. All agents in the habitat are checkpointed to the database, as well as the state of the JNDI registry (where all the agent names and locations are stored). After a restart, the agents will continue where they left off.

  • Are agents persistent over time? Which databases are currently supported?

As of ADK 2.0, persistency is pre-configured using hsqldb. The habitat must be connected to a database to use the persistency feature. Using databases other than hsqldb must be properly installed and configured with the ARE. The ADK currently supports habitat persistence using the following databases: HSQLDB, Mckoi, MS-SQL Server 2000, DB2, MySQL, PostgreSQL, Oracle 8 or higher, and Cloudscape (as of ADK 3.0).

  • How do agents implement persistence?
  1. Agents are checkpointed when they are created, when they arrive in a new habitat, and on request (e.g. after a transaction). This makes it possible to recover them after a system crash or shutdown.
  2. Agents are suspended on request. They are almost completely removed from the habitat and stored in the database, eliminating their resource usage. Their suspended state is fully transparent to other agents; they are automatically resumed whenever a message arrives or when a preset timer expires.
  • How do I connect to databases to implement persistence?

If using a database other than the pre-configured hsqldb, after installing the database, you must add several properties to the config\habitat.properties file. The appropriate database drivers must also be installed. Habitat command line options are used to control and further configure persistence. For detailed information and further instruction, refer to the ADK Quickstart Guide (release 1.3.10 and higher).

PERFORMANCE

  • What’s the size of the agent with a 4k data payload?

The agent’s memory footprint would be in the order of 12k+, depending on the amount of user code that is also in the agent. The amount of data sent over the wire when the agent moves would be in the order of 12k + 5k overhead for signatures, etc. The size of the user code is in addition to this overhead when the agent moves to a new location.

  • How many agents can run at one time? How much memory is typically used per agent? How much CPU time is used?

This completely depends on the nature of your agent and/or agent application. However, we have a few benchmark figures.

The JVM itself takes 12MB of memory. The ARE (Agent Runtime Environment) takes approximately 1MB of memory. The remaining memory of your system is available to the agents.

During stress tests performed in our real-life applications (dating using SMS and the Internet), we averaged on 30Kb per agent. A simple agent using messaging and mobility is typically below 10Kb in size.

The CPU time depends on the tasks your agent application attempts to perform and some settings in the Habitat that control the number of concurrent threads. (This does not limit the number of agents; the ARE can map several agents to the same thread).

  • Can I make blocking calls in my agent?

Not really. The agent model follows the Swing GUI model in this respect. If you perform a blocking call within a Swing thread, the entire GUI would stall. To prevent this, normally you create another thread and execute the blocking call within that thread. This keeps the GUI running while the call is waiting for a response. When the response comes in, the thread will provide the Swing GUI with the information needed, for instance, via a listener mechanism or message queue. Likewise, agents need to keep running.

More information can be found under the Agent Specification section.

  • Are there any documented benchmarks for mobile agents over various network bandwidths?


We don’t have any off-the-shelf data publicly available. However, agent transport is highly optimized, only transferring those code parts not currently present in the target environment. Please contact us if you want more information about the ADK performances.

TROUBLESHOOTING

  • When I start my habitat, a huge amount of text starts pouring over my screen. Why is this happening and how can I prevent it?


This occurs when the log directory is not present or cannot be written to. The habitat tries to write its (XML) logging to the directory specified in config\habitat.properties by the property com.tryllian.log.system.logdir. If this is impossible, the logging is sent to standard output (usually the screen).

  • My habitat tells me I’ve got a “corrupted jarcache”. What’s a jarcache, how does it become corrupted, and what can I do about it?

The jar cache stores the jarfiles that are needed to create the agents in your system. It is closely synchronized with your persistent storage facility, and when the two become out of sync, you can get this error. This can also be caused by deleting jar cache files in your temporary directory. In this situation, your only option is to empty the jar cache directory and re-create your database. When you shutdown or startup a habitat, the unused jarfiles are automatically removed.

GENERAL QUESTIONS

  • How much coding is involved in creating an agent system?

This completely depends on the nature of the agent system. However, given the fact that agents are highly modular, they can use almost every library available through Java 2 Standard Edition. They can use a high-level abstraction layer (the AFC) with relatively little additional coding.

  • How to debug agents using a source code debugger?

The developer guide contains a chapter on how to run a habitat in a source code debugger. The instructions given in this chapter are quite complex, and also very much specific to the source code debugger used.

It is however possible to run a habitat in debugging mode using a remote source code debugger. This remote debugger may run on the same machine, or on a different machine. The general setup, which should work with any IDE supporting remote debugging, is as follows:

  • start a habitat in debugging mode. The habitat will wait for a connection from a remote debugger.
  • startup your IDE, and specify where your source code is
  • setup a breakpoint
  • attach to the java process running the habitat
  • the moment the breakpoint is hit, the debugger will be activated, and you are able to step though the source code, watch variables etc.

Refer to the manuals of your IDE to learn more about the specifics of running a remote debugger. The instructions here have been written using NetBeans on Linux and Windows 2000, but have also been tested using JSwat on Linux and the standard Java debugger jdb on Linux.

Below are the more detailed instructions.

Starting a habitat in debugging mode on Linux or Solaris

Add the following options to your habitat startup script

-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y

This will enable debugging in the JVM. The JVM will wait for a debugger connection on port 8000.

After running the new script, the Java VM starts up, waiting for the debugger connection.

More information on the remote debugging interface can be found on http://java.sun.com/j2se/1.3/docs/tooldocs/solaris/jdb.html.

Starting a habitat in debugging mode on Windows

Add the same arguments as above to your startup script. We recommend to use the socket connection method. We experienced problems using the default shared memory transport.

After running the new script, the Java VM starts up, waiting for the debugger connection.

More information on the remote debugging interface can be found on http://java.sun.com/j2se/1.3/docs/tooldocs/win32/jdb.html.

Note that older versions of JDK 1.3.1 on Windows have problems running the remote debugger. It is advised to run the most recent version of JDK 1.3.1. Currently the most recent version is 1.3.1_07.

Startup your IDE and tell it where your source code is

This is depending on your specific IDE. As an example, the steps using NetBeans are presented here.

After starting up, use the File/Mount FileSystem to mount the source code tree. Normally, you would want to mount the whole source tree of a package by mounting the folder containing the first component of the package name. So mount the “src” directory if your package tree is located in the “src” directory.

Setup a break point

Open the source file, select the source code line you are interested in, and add a breakpoint, by clicking in the gray margin of your source code view.

Attach to the JVM running the habitat

In Netbeans, choose Debug/Add Session/Attach on port 8000 on Linux or Solaris. On Windows, use connector SocketTransport and port 8000, The JVM will start running, and the moment the breakpoint is hit, the IDE will show you that.

CONTACT TRYLLIAN

  • Help! I still have more questions!

Go the Mailing Lists page and search through the archives, or post your question on the relevant mailing list: the users mailing for developers programming with the ADK, or the develioers mailing list for developers programming on the ADK. Tryllian developers are present on both mailings lists so don’t worry that we won’t see your questions.