Chapter 7. Deployment

Table of Contents

7.1. Deploying an Agent
7.1.1. Overview
7.1.2. Structure of the DNA file
7.1.3. The agent descriptor
7.1.4. Resolving shared references
7.1.5. Using resources
7.1.6. Creating DNA files
7.1.7. Updating DNA files
7.1.8. The API
7.2. Properties
7.2.1. External
7.2.2. Identification
7.2.3. System Load
7.2.4. Security
7.2.5. Logging
7.2.6. Miscellaneous
7.2.7. Persistency
7.2.8. Messenger
7.3. Format of the Habitat XML file
7.4. Habitats and Databases
7.4.1. Database support

7.1. Deploying an Agent

This section describes how agents are deployed using the dnacomposer: the API and the toolkit that can be used to create DNA files. DNA files contain agents: their class definititions, library jar files and resources.

7.1.1. Overview

Agents are deployed by storing their code and resources in a so called DNA file[14]. DNA files are signed by their developer, thus making it possible to assign permissions to agents. From a single DNA file, multiple agents can be created.

The ARE makes it possible for agents defined in different dna files to share jarfiles. The agent descriptor DTD defines the shared-ref tag for this. Shared references point to jarfiles external to the DNA file. Jarfiles contained in a DNA file can not be shared by agents created from different DNA files.

DNA files are created using the command-line DNA-composition utility dnacomposer, which has the following features:

  • Create DNA files

  • Upgrade DNA files by replacing a subset of the jarfiles contained by the DNA file.

  • Delivered both as a command-line tool and as a library that can be used from agent code.

7.1.2. Structure of the DNA file

A DNA file is a jarfile that contains jarfiles, an agentdescriptor file, and zero or more resources. The individual jarfiles are signed, just like the entire DNA file. Signing the entire DNA file ensures that the composition itself is not changed, while signing individual jarfiles makes it possible to optimize the transport of individual jarfiles.

The agentdescriptor file is a description of the various parts that are needed for an agent to function, using XML syntax and the DTD specified below.

Graphically, DNA files have the following structure.


myagent.dna
|
+----META-INF
|    |
|    `<security information>
|
+----descriptor.xml
|
+----jarfile.jar
|    |
|    +----META-INF
|    |    |
|    |    `<security information>
|    |
|    `----<class files>
|
`----resources.jar
     |
     +----META-INF
     |    |
     |    `<security information>
     |
     `----<resource files>


    

Note

Every jarfile contained in the DNA file must be specified in the agent descriptor with the <file> tag; every jarfile specified in the agent descriptor using the <file> must be contained in the DNA file.

Jarfiles specified in the agent descriptor using the <shared-ref> tag must not be contained in the DNA file.

7.1.3. The agent descriptor

The agent descriptor is an XML file specifying the constituent parts of the agent. Furthermore, it contains some meta information on the agent itself. The agent descriptor must conform to the following DTD:


<!--
The top tag is "agentdescriptor".
It has a "version" attribute which should be set to the value "1.0"
-->
<!ELEMENT agentdescriptor (agenttypedescription, target+)>
<!ATTLIST agentdescriptor
        version   CDATA      "1.0"
>

<!-- 
The first subtag under agentdescriptor is agenttypedescription.
This is a string describing, in human language, the functionality
of this type of agent.
-->
<!ELEMENT agenttypedescription (#PCDATA)>

<!--
The second subtag under agentdescriptor is target.
There can be multiple targets for one agentdescriptor.
It has a unique id for an attribute.
-->
<!ELEMENT target (environment, shared-ref*, file*)>
<!ATTLIST target
        target-id   ID      #REQUIRED
>

<!--
The first subtag under target is environment.
Because of the fact that programming languages define themselves in various
ways, each environment has its own subtag. For now, only java is permitted.
-->
<!ELEMENT environment (java)>

<!--
A specific version of the Java language can be defined in terms of
various specifications:

One or more comma separated supported ARE versions
One main class for the agent
-->
<!ELEMENT java (EMPTY)>

<!ATTLIST java
        areversions CDATA   "1.3"
        agentclass  CDATA   #REQUIRED
>

<!--
Another subtag of target is file. This is a string defining a file
that is part of the necessary 'luggage' required for running the
agent on this/these target(s). If located in a subdirectory of
the jar, forward slashes are used to indicate subdirectories.
-->
<!ELEMENT file (EMPTY)>
<!ATTLIST file
    name    CDATA   #REQUIRED
>

<!--
Some files are more basic than others. They are usually shared among
multiple agents, regardless of other luggage. Special files are used to
indicate such files.

The type of a shared reference indicates how to the system should treat
the file. Currently only the value 'stdlib' is allowed; its value is
currently not used.
-->
<!ELEMENT shared-ref (EMPTY)>
<!ATTLIST shared-ref
	type    (stdlib)       "stdlib"
	name    CDATA           #REQUIRED>

    

Example 7.1. An example descriptor


<!-- A descriptor for the DNA file of the Hello World agent. -->

<agentdescriptor>
    <target target-id="standard">
        <environment>
            <java areversions="1.3"
                agentclass="tryllian.scenarios.helloworld.HelloWorldAgent"
            />
        </environment>
        <file name="helloworld.jar"/>
        <shared-ref type="stdlib" name="afc"/>
    </target>
</agentdescriptor>

      

Note

Filenames and shared references specified in the agent descriptor must not contain forward or backward slashes.

7.1.4. Resolving shared references

Shared references are references to jarfiles outside the DNA file. In the agent descriptor they are specified using a short name. When an agent is deployed, this name must be resolved. When the DNA file is created, the name should not be resolved.

Name resolution is done through a catalog file, which must be named dna.catalog. This file resides in the ARE configuration directory[15].

The catalog is a simple property file which maps names to URLs. These URLs can point to other computers, as long as the associated data can be retrieved. URLs can contain properties defined in the habitat properties.

Example 7.2. Example catalog file


# Example DNA catalog
my_reference=file:${are.home}/lib/somefile.jar
your_reference=http://www.your_host.eu/euro.jar
        
      

This example catalog file contains all that is allowed; it starts with a comment and is followed by two mappings. The first mapping maps the name my_reference to the file somefile.jar. The exact location of this file is determined by the value of the are.home property.

The second mapping maps the name your_reference to a file on a web server.

It is important that the files pointed to by the shared references are themselves signed as well. If they are not signed, they will get the security role assigned to unsigned code, which is very restrictive.

7.1.5. Using resources

Note

From a technical point of view, resources are not different from class files. As such, they must be contained in jarfiles. This is comparable to any other Java application.

Resources, such as images or XML files, can be stored inside the DNA file by first wrapping them in a jarfile. This can be a jarfile already used for storing code, or a separate jarfile.

Agents can then retrieve these resources from their DNA file as they would with ordinary jarfiles, i.e. by using the Class.getResource and Class.getResourceAsStream methods. As in any other Java application, such resources are not modifiable.

7.1.6. Creating DNA files

When a DNA file is created, the following happens:

  1. The agentdescriptor is read and stored in the new DNA file.

  2. For every <file> specified in the descriptor, a jarfile with a corresponding name is searched for in the jarpath directory. (The jarpath is specified by the caller).

  3. The jarfiles are stored in the new DNA file. They are signed upon storing; the original jarfiles are not touched.

  4. The entire DNA file is signed as well.

7.1.7. Updating DNA files

When a DNA file is updated, the following happens.

  1. If a new agent descriptor is specified, it is read and stored in the new DNA file. If it is not specified, it is copied from the original DNA file.

  2. For every <file> specified in the descriptor, the following happens:

    1. If a jarfile with this name is specified by the caller, it is signed and stored in the new DNA file. The original jarfile is not modified.

    2. If the jarfile is not specified, it is copied from the original DNA file to the new DNA file.

      If the code has been signed by a different certificate than the certificate that is used when upgrading, the following happens:

      1. The original signature is removed.

      2. The code is signed with the specified certificate.

      If the code was signed with the same certificate as the specified certificate, nothing happens.

  3. When all relevant jarfiles have been stored in the new DNA file, the entire DNA file is signed as well.

7.1.8. The API

Agents can use the dnacomposer by requesting an object of the type tryllian.are.security.DNAComposer.

It is also possible to use the dnacomposer command-line tool, as specified in The DNA composer tool.

Agents can use the update functionality of the DNA composer to create new DNA files based on old DNA files. Combined with the upgrade-agent protocol (The upgrade-agent protocol), this can be used to update agents on the fly.

While the command-line tool has a sensible default for the jarpath, the API does not; it must be set.

7.2. Properties

This section describes which properties can be used by the Habitat. Properties are defined in a properties file, which contains keys and values separated by '=' signs.

Although, technically, values are always strings, the ARE supports four types of interpretations:

string

The string interpretation is identical to the value.

"hello word" -> "hello world"

integer

The integer interpretation is a base 10 decoding of the value; the value should only contain digits.

"1224" -> 1224

boolean

The boolean interpretation is straightforward: the value true is interpreted as true, the value false is interpreted as false.

"true" -> true

list

The list interpretation uses the comma and/or whitespace as separators. The respective elements are then interpreted again.

"1 2 3 4" -> [1, 2, 3, 4]

The type of interpretation depends on the meaning of the property.

A property value can also refer to the value of another property by putting the name of that property between ${ and }. For example, the property myfile=${are.home}/file.txt refers to the file file.txt that resides in the directory pointed to by are.home. These property names can be both ARE properties and java properties[16].

Default values specified here are the values used if nothing is specified; they should not be confused with the values that are in your configuration file by default.

If you are writing extensions to the ARE such as messenger or database plugins you will have occasion to access the ARE properties from code. Please consult the javadoc of the AREPropertyBase class and the PropertyFacade class from the are-common.jar library.

7.2.1. External

There are a few properties that can not be set in the habitat.properties file because they are required for bootstrapping. These properties can be given at the command line using the java -D options.

All other properties can be set in the habitat.properties file or on the command-line.

These options are referred to from the habitat.properties file.

PropertyDescriptionDefault
are.home The root-directory of the distribution (as far as the ARE is concerned). The scripts in the distribution derive their value from the ADK_ROOT environment variable. No default.
are.configdir The directory containing the configuration files for the Habitat. It is used to initially find the habitat.properties file. ${are.home}/config

7.2.2. Identification

Sometimes the ARE is not able to discover its own identity. There are three properties that can be set in these cases.

PropertyDescriptionDefault
are.localhost.name The hostname or IP-address of this machine. On some machines, the ARE can only detect the IP address 127.0.0.1, in which case the network will be disabled. By setting this property, the ARE's autodetection is overridden. As resolved by java.net.InetAddress.
habitat.id The Habitat ID. This property is here for backwards compatibility only; Habitat IDs should now be derived from the Habitat certificate, as described in Section 6.1.10, “Certificates and Habitat IDs”. Derived from IP address and habitat identification port number.
habitat.identification.portIf you are running more than one habitat or standalone messenger on a single machine. You may set the identity port number, to distinguish between the different habitats. The identity port is used to compute the habitat id. The corresponding tcp-ip port is locked to prevent two habitats from running with the same identity at the same time. If not set, and if 50000 isn't free, the ARE adds 1 to the default 50000 until a free portnumber is found. Note that this portnumber is used to compute the habitat id if the habitat id is not set either in the certificate or in the property habitat.id, and that this heuristic means that habitat-id's can change from run to run. 50000

7.2.3. System Load

Even though Java does not offer much resource protection, the ARE provides some safeguards to prevent a Habitat from starving your system of memory or CPU.

PropertyDescriptionDefault
executionmanager.eventdispatcher.threadcount The number of threads reserved for executing agents events. The higher the number, the more threads your system will spawn. If this number is too low, you might starve some agents. (This is not the number of long term threads the agent can request from the ExecututionContext, which is hard-coded to ten.) 10
executionmanager.eventdispatcher.minimumtimesliceinterval On quiet systems, heartbeats can be dispatched at very high rates, causing a huge CPU load. Therefore, the ARE makes sure there is a minimum interval between hearbeats, specified in milliseconds.[17] 100
executionmanager.threaddispatcher.threadcount The maximum number of long-term threads (Routines) that can be active at any time. 10

7.2.4. Security

Apart from all the certificate related settings, the ARE also offers some properties to influence secure behavior.

PropertyDescriptionDefault
security.role.no_cert The role assigned to unsigned agents. This property can be used to distinguish unsigned agents from agents with an unknown certificate. NoCert
cloning.supported Whether or not the clone protocol is supported; this can be used to prevent clone-bombs. false
cloning.workload The maximum amount of clones that can be created in one pass. 0 indicates no maximum. 10
cloning.queue.length The number of clone requests that can be queued for a given agent at any time. 0 indicates no maximum. 10
security.roles_prop.location The name of the file where roles are assigned to certificates. If the name is relative, it is resolved against the configuration directory. roles.prop
security.roles.dir The directory where the role definitions reside. If the name is relative, it is resolved against the configuration directory. roles
security.keystore.location The filename of the keystore containing agent certificates; this is the keystore that is used to assign roles to incoming agents. If it is a relative name, it is resolved against the configuration directory. keystore.dat

7.2.5. Logging

The behavior of the logging system can be slightly modified using a number of properties. For vastly different behavior, it is necessary to create a subclass of com.tryllian.log.LogSystem.

The ARE currently supports three kinds of LogSystems: the com.tryllian.log.system.DefaultLogSystem, which writes monolithical logfiles, the com.tryllian.log.nullsystem.NullSystem, which does not output any logging information, and the com.tryllian.log.system.RotatingLogSystem, which sends its logs to the Unix rotatelogs command, resulting in more, smaller logfiles. The latter is especially useful for server situations.

PropertyDescriptionDefault
tryllian.log.log-system-class The class to use for generating the logs. com.tryllian.log.system.DefaultLogSystem.
com.tryllian.log.system.logdir The directory where the DefaultLogSystem and the RotatingLogSystem will write their logfiles. Current working directory
com.tryllian.log.system.level The level (threshold) for logging events. Entries for the log with a priority lower that this level will not be logged. You can use this option to reduce the amount of logging. Valid values are emerg, alert, crit, error, warn, notice, info, debug, debug1, debug2, debug3 and debug4. These match their equivalent in tryllian.log.LoggingConstants. tryllian.log.LoggingConstants.PRIO_LOWEST
com.tryllian.log.system.rotatelogs The rotatelogs command to use by the RotatingLogSystem. /usr/sbin/rotatelogs
com.tryllian.log.system.rotelogs.period [18] The number of seconds between log-rotations. 86400 (24 hours)
messagebroker.keepmessagelog If set to true, the message broker will log every message. This is great for debugging, but will result in huge logfiles. false

7.2.6. Miscellaneous

PropertyDescriptionDefault
classloader.basedir Whenever a DNA file with a relative pathname is loaded, it is resolved against the classloader basedir. Current directory
statistics.interval-seconds The number of seconds between two inform statistics messages. 300

7.2.7. Persistency

The persistency support in the ARE is regulated by the following properties.

PropertyDescriptionExample
properties.wakeupsa.wakeup-interval-seconds The period the Wakeup Systemagent sleeps before waking up suspended agents in seconds. Defaults to 1 minute; that means that unless they get a message, agents will sleep at least one minute. 60
db.jdbc2.plugin The Habitat plugin used for communication with the database com.tryllian.are.jdbc.Plugin
db.jdbc2.driver The full classname of the JDBC driver that is to be used. oracle.jdbc.driver.OracleDriver
db.jdbc2.url The JDBC URL used to connect to the database. jdbc:oracle:thin:@databaseserver:1521:database
db.jdbc2.user The username with which to login. For some databases, this can also be provided in the JDBC URL. gaston
db.jdbc2.password The password with which to login. For some databases. this can also be provided in the JDBC URL. sqrtxsprotlub
db.jdbc2.connections.max The maximum number of connections the Habitat may open. If unspecified, the default value of 10 will be used. 10

Besides persistency support with an external database, there are other persistent data that are stored outside of the database. See Section 7.4, “Habitats and Databases”.

PropertyDescriptionDefault
jarcache.basedir Directory where files can be created for storage of shared jarfiles. A relative directory will be resolved against the current directory (java's ${user.dir}) during system-startup. The directory will be created if it does not exist. The directory must not be shared between multiple habitats. JarFiles in this directory may be deleted for garbage collection. ${java.io.tmpdir}

7.2.8. Messenger

The ARE messenger architecture consists of two parts: the messenger plugins on the one side, and the messenger registry on the other side. Messenger plugins utilize some transport mechanism, like JXTA or SOAP, to transport messages. Which properties are appropriate depends upon the type of messenger plugin.

7.2.8.1. Messenger Registry Properties

PropertyDescriptionDefault
messenger.rmi.remote-allowedIf this property is set to false (default) then externally started messengers cannot register themselves with this habitat. Setting this to true is a security-related decision. false
messenger.jndi.refresh.intervalThe interval between periodic publish and log of discovered habitats.20
messenger.rmi.hostThe hostname the messenger plugin registry will use to bind itself to in the RMI registry. localhost
messenger.rmi.portBoth the portnumber of the RMI registry that the messenger registry will start and the portnumber under which the messenger registry will register itself with the rmi registry.1099
messenger.rmi.nameThe name the messenger registry will use to register itself with the RMI registry. If empty, the habitat id will be used.habitat ID
messenger.registry.startmessengersThis property determines which messengers are started automatically in the habitat jvm. By default the JXTA Messenger Plugin will be used. This plugin is compatible with the messengers in previous releases of the ARE. (Note: in the future, we will provide a second JXTA Messenger Plugin that uses the most recent version of JXTA which is incompatible with older versions of JXTA.) com.tryllian.messenger.jxta.JXTAMessengerPlugin

7.2.8.2. Messenger Plugin Properties

Depending on which plugin is used, the messenger plugin may need any or all of the messenger properties detailed below. However, there are two properties used only when messenger plugins are started standalone. They have the same function as the are.home and are.configdir properties detailed above.

PropertyDescriptionDefault
messenger.configdirThe location of the messenger properties file. Empty by default. A properties file is not necessary: all necessary properties can also be given on the command line.
messenger.propertiesThe base file name of the properties file for the messenger plugin.

7.2.8.3. Standalone Messenger Properties

PropertyDescriptionDefault
messenger.habitat-id An ID Reference (q.v.) indicating the Habitat ID. If the Habitat ID is specified in the Habitat's certificate, this property will be ignored. No default; this property is required.
messenger.agent-id An ID Reference (q.v.) indicating the Agent ID associated with the messenger. random local ID Reference.

7.2.8.4. JXTA Messenger Properties

The JXTA Messenger properties distinguish three kinds of properties: those specifying the ports used for incoming traffic, those specifying how outgoing traffic is handled and how the JXTA Messenger interacts with other peers.

Below, the following conventions will be used:

address

An address is a string containing a fully qualified hostname or an IP address.

myhost.mydomain, 192.168.1.1

port

A port is an integer in the range [1..65535]. Remember that UNIX systems consider the range [1..1024] to be privileged ports.

9700

endpoint

An endpoint is a combination of an address and a port, separated by a colon.

myhost.mydomain:9700, 192.168.1.1:8080

URL

A URL is a fully qualified address, i.e. a combination of a protocol, an address and a port

http://myhost.mydomain:9700, tcp://192.168.1.1:76

PropertyDescriptionDefault
messenger.listen.tcp A boolean indicating whether or not the Habitat will listen on TCP. true
messenger.listen.tcp.address The address of the interface on which the messenger will listen for TCP traffic. Obtained from java.net.InetAddress
messenger.listen.tcp.port The port on which the messenger will listen for TCP traffic. 30434
messenger.listen.tcp.nat.endpoint If the messenger resides behind a NAT machine, specifying the NAT endpoint will optimize the routing of incoming replies over TCP. If it is not specified, no NAT endpoint will be used. None
messenger.listen.http A boolean indicating whether or not the Habitat will listen on HTTP. This property has no effect unless messenger.is.relay is set to true as well. true
messenger.listen.http.address The address of the interface on which the messenger will listen to incoming HTTP traffic. Obtained from java.net.InetAddress.
messenger.listen.http.port The port on which the messenger will listen to incoming HTTP traffic. 30435
messenger.use.rendez-vous.urls A list of URLs indicating the rendez-vous hosts that can be used by this machine. Both HTTP and TCP rendez-vous URLs are allowed. none
messenger.use.http.proxy.endpoint The endpoint of the HTTP proxy server to use for outgoing HTTP traffic. none
messenger.use.http.relay.endpoints The endpoints of the relays used to translate between HTTP and TCP. none
messenger.is.rendez-vous Boolean indicating whether the messenger will act as a rendez-vous peer for other peers. false
messenger.is.relay Boolean indicating whether the messenger will act as a relay. false
messenger.is.relay.nat.endpoint The endpoint used to relay between HTTP to TCP traffic; if the Habitat is behind NAT, it is preferable to specify the NAT address to optimize routing. Value of property messenger.listen.http.address
messenger.keep.alive.time The time in seconds how long the messenger keeps a connected pipe after its last use (sending or receiving a message). 300
messenger.discovery.interval The interval time in seconds between successive sending out of discovery requests. 60
messenger.jndi.refresh.interval The interval time in seconds between the updating discovery information available via JNDI. 20
messenger.delivery.timeout The message timeout value in seconds. This is the maximum time a message will be queued in the upper protocol layers. Note that the actual delivery may take longer, because the lower protocol layers may take some time to do their work. 60
messenger.publish.max-interval The maximum publish interval in seconds. A messenger publishes its advertisements periodically. The length of this interval is determined by the messenger, with the value of this property as a maximum. 3600
messenger.verbose Whether the JXTA messenger prints debug output. This output is meant for ADK specialist use only. false

7.2.8.5. Secure JXTA Messenger Properties

PropertyDescriptionExample
messenger.security.private-keystore A URL defining the keystore containing the key entry that contains the Habitat key pair and the Habitat ID. Default is file:${are.configdir}/habitat-private-keystore.dat file:${are.configdir}/someKeyStore.dat
messenger.security.private-keystore.password The password associated with the private key store. No default value. secret
messenger.security.private-keystore.entry.alias The alias of the keystore entry that holds the private key entry. Default habitat. my-key
messenger.security.private-keystore.entry.password The password associated with the keystore key entry that contains the private key. Default: same as keystore password. secret
messenger.security.trusted-keystore A URL defining the keystore containing the list of trusted certificates. Default file:${are.configdir}/trusted-keystore.dat. file:${are.configdir}/someKeyStore.dat
messenger.security.trusted-keystore.password The password associated with the trusted key store. No default value. Note that if no password is given , the keystore cannot be checked for integrity. secret
messenger.security.revoked-keystore A URL defining the keystore containing the list of revoked certificates. Default file:${are.configdir}/revoked-keystore.dat. file:${are.configdir}/someKeystore.dat
messenger.security.revoked-keystore.password The password associated with the revoked key store. No default value. Note that if no password is given , the keystore cannot be checked for integrity. secret
messenger.advertise.secure-pipe If set to true, this Habitat will only use secure pipes. If set to false, this Habitat will only use insecure pipes. true
messenger.security.use.custom-trust-model Defines the trust model to use. If set to true, the trust model in Section 6.1.6, “Trust model” will be used. Otherwise, only those authentication and encryption steps required by the TLS will be used. This property is only relevant if messenger.advertise.secure-pipe is set to true. false
messenger.security.use.unsecure.random-seed Use an unsecure, but faster method of seeding the secure random generator. This may be needed for slower machines. false

While keystores can be identified by all kinds of URLs, file URLs provide the safest solution. For example, obtaining the contents of a keystore over HTTP is not explicitly secured by the ARE. This can however be useful in networks that are physically closed.

7.3. Format of the Habitat XML file

The initial lay-out of a Habitat is described by an XML file. This file describes the the agents that should be created on startup.

The full DTD is given below. Its official definition can be found at http://www.tryllian.com/xml/habitat_1_1.dtd.

    
<!-- Every file is contained in the 'habitat' element -->
<!ELEMENT habitat   ((on-exception)?, (agent)*)>


<!ELEMENT on-exception EMPTY>
<!ATTLIST on-exception
    action      (stop | silent | log)       "log"
>

<!-- The agent element defines an agent in the habitat -->
<!ELEMENT agent (arg)*>
<!ATTLIST agent
    nickname    CDATA       ""
    dna         CDATA       #REQUIRED
    habitat     CDATA       #IMPLIED
>

<!-- An agent argument. This is passed to the agent immediately -->
<!ELEMENT arg EMPTY>
<!ATTLIST arg
    value       CDATA       #REQUIRED
>            
  

Example 7.3. An example Habitat XML file

      
      <!DOCTYPE habitat "http://www.tryllian.com/xml/habitat_1_0.dtd">

      <habitat>
      <on-exception action="stop"/>

          <agent dna="httpservice.dna">
          <arg value="8080"/>
          </agent>
    
          <agent dna="soapservice.dna"/>
     </habitat>
                
    

The on-exception tag describes what to do when the habitat could not be started. The values for the parameter action have the following meaning:

log

Log the error to logoutput.xml and try to continue.

silent

Do not mention the error and try to continue.

stop

Show the error on screen and stop the entire process.

The tag agent describes an agent that should be added. Every agent tag adds exactly one agent. The attributes have the following meaning:

dna

The location of the DNA file. Relative files are resolved against the classloader.basedir property. Absolute files are allowed, but only if they lie within the path specified in the classloader.basedir property.

Note

The on-exception tag replaces the old onException tag.

7.4. Habitats and Databases

If you want to provide the agents on your Habitat with persistence, it is mandatory that the Habitat is connected to a database. This section describes how to set up the database and connect it to the Habitat.

Note

The current implementation also uses storage outside the database, but does not provide an alternative. This storage is currently required. This storage contains shared jar-files, and are stored outside the database for reasons of performance.

The ARE currently supports two kinds of persistence. First, there is agent persistence, which takes care of persisting individual agents. Secondly, the ARE provides JNDI persistence, which takes care of supporting the JNDI tables.

The ARE uses JDBC for connecting to the database. Refer to The JDBC™ Data Access API for more information.

In previous versions of the ARE it was theoretically possible to share databases between instances of the ARE. This is no longer supported. The disadvantage of sharing a database by habitats is that the clean-up and garbage collection is fragile. The advantage was that it would be theoretically possible to share JNDI data between habitats sharing the same database. The advantage of the new sitation is that if the habitat-id changes between sessions of the habitat, the agents will be depersisted into the habitat associated with the same particular installation of the ADK.

7.4.1. Database support

The ARE officially supports seven kinds of databases. These are the following:

DatabasePurposeLimitations
hsqldb A small, free-of-charge database which can be run in the same VM as the habitat. It allows fully automatic database deployment for small setups. JNDI paths can be up to 1600 characters long. Place paths can be at most 2000 characters long. Serialized agents of up to 6 MB can be handled without difficulties.
Cloudscape Cloudscape was bought recently by IBM from Informix. Cloudscape is a small-footprint, standards-based, relational Java database that can is tightly embedded in the ARE. Delivers a migration path to DB2 (which the ARE doesn't support yet). Cloudscape is not free. JNDI paths can be up to 1600 characters long. Place paths can be up to 2000 characters long. jar ID are limited to 1000 characters long. Serialized agents of up to 100 MB can be handled without difficulties.
McKoi A small, free-of-charge database which can be run in the same VM as the habitat. It allows almost fully automatic database deployment for small setups. JNDI paths can be up to 1600 characters long. Place paths can be at most 2000 characters long. Serialized agents of up to 20 MB can be handled without difficulties.
MS SQL Microsoft's professional SQL server. It requires a separate JDBC driver from a third party vendor. JNDI paths and place paths can be up to 800 characters long. Serialized agents have a maximum of 2 Gb.
Oracle 8i One of the biggest players in large scale database applications. Especially suited for habitats that require tens of thousands of agents. It requires an Oracle JDBC 2.0 driver, such as the Thin driver or the OCI driver. JNDI paths can be up to 1600 characters long. Place paths can be up to 2000 characters long. Using the Thin driver, serialized agents over 5 MB result in performance hits. This can be improved by using the OCI driver.
Oracle 8i One of the biggest players in large scale database applications. Especially suited for habitats that require tens of thousands of agents. It requires an Oracle JDBC 2.0 driver, such as the Thin driver or the OCI driver. JNDI paths can be up to 1600 characters long. Place paths can be up to 2000 characters long. Using the Thin driver, serialized agents over 5 MB result in performance hits. This can be improved by using the OCI driver.
PostgreSQL Postgres is a popular open source database, which adheres closely to SQL standards. JNDI paths can be up to 1600 characters long.
MySQL 4.1 MySQL is another very popular open source database. You need at least version 4.1, with support for InnoDB. Older versions lack support for certain required features. JNDI paths can be up to 255 characters. It is very important to keep in mind that MySQL silently truncates these, which may result in unpredictable behavior. Another limitation is placed on the length of the name of the jars used by your agent, keep these below 160 characters.

The database layer tries to do as much as possible in a generic way. However, due to small deviations from ANSI SQL 92 and optimalization, the setup of the database (creating tables and indexes) can not be generalized. The ARE must try to minimize the number of steps required for setting up a database.

All other database-related activities will be done using JDBC 2.0 and ANSI SQL 92. This will make it possible to quickly extend database support, if so desired. However, JDBC has two drawbacks:

  • For most databases, there is special support in the JDBC code to optimize database usage, which cannot be generalized. This means that separate, database specific drivers must be written if performance is a bottleneck.

  • BLOB [19] support is defective in the JDBC 2.0 specification. This will be circumvented by using large binary strings, which are supported by both JDBC 2.0 and ANSI SQL 92. JDBC 3.0 might remove this problem in the future.



[14] DNA stands for Definition of a New Agent.

[15] The ARE configuration directory is defined by the property are.configdir in the habitat startup script.

[16] Java properties are those properties that can be obtained by using the System.getProperty method. Please refer to the java.lang.System javadoc for more information.

[17] This property should be called minimum-heartbeat-interval, but for historical reasons it isn't.

[18] Yes, it says rotelogs instead of rotatelogs.

[19] Binary Large OBjects, such as the serialized data of an agent.