Table of Contents
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.
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.
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>
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.
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>
Filenames and shared references specified in the agent descriptor must not contain forward or backward slashes.
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.
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.
When a DNA file is created, the following happens:
The agentdescriptor is read and stored in the new DNA file.
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).
The jarfiles are stored in the new DNA file. They are signed upon storing; the original jarfiles are not touched.
The entire DNA file is signed as well.
When a DNA file is updated, the following happens.
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.
For every <file> specified in the descriptor, the following happens:
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.
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:
The original signature is removed.
The code is signed with the specified certificate.
If the code was signed with the same certificate as the specified certificate, nothing happens.
When all relevant jarfiles have been stored in the new DNA file, the entire DNA file is signed as well.
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.
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:
The string interpretation is identical to the value.
"hello word" -> "hello world"
The integer interpretation is a base 10 decoding of the value; the value should only contain digits.
"1224" -> 1224
The boolean interpretation is straightforward: the value true is interpreted as true, the value false is interpreted as false.
"true" -> true
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.
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.
| Property | Description | Default |
|---|---|---|
| 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 |
Sometimes the ARE is not able to discover its own identity. There are three properties that can be set in these cases.
| Property | Description | Default |
|---|---|---|
| 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.port | If 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 |
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.
| Property | Description | Default |
|---|---|---|
| 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 |
Apart from all the certificate related settings, the ARE also offers some properties to influence secure behavior.
| Property | Description | Default |
|---|---|---|
| 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 |
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.
| Property | Description | Default |
|---|---|---|
| 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 |
| Property | Description | Default |
|---|---|---|
| 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 |
The persistency support in the ARE is regulated by the following properties.
| Property | Description | Example |
|---|---|---|
| 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”.
| Property | Description | Default |
|---|---|---|
| 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} |
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.
| Property | Description | Default |
|---|---|---|
| messenger.rmi.remote-allowed | If 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.interval | The interval between periodic publish and log of discovered habitats. | 20 |
| messenger.rmi.host | The hostname the messenger plugin registry will use to bind itself to in the RMI registry. | localhost |
| messenger.rmi.port | Both 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.name | The 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.startmessengers | This 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 |
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.
| Property | Description | Default |
|---|---|---|
| messenger.configdir | The 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.properties | The base file name of the properties file for the messenger plugin. |
| Property | Description | Default |
|---|---|---|
| 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. |
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:
An address is a string containing a fully qualified hostname or an IP address.
myhost.mydomain, 192.168.1.1
A port is an integer in the range [1..65535]. Remember that UNIX systems consider the range [1..1024] to be privileged ports.
9700
An endpoint is a combination of an address and a port, separated by a colon.
myhost.mydomain:9700, 192.168.1.1:8080
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
| Property | Description | Default |
|---|---|---|
| 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 |
| Property | Description | Example |
|---|---|---|
| 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.
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 the error to logoutput.xml and try to continue.
Do not mention the error and try to continue.
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:
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.
The on-exception tag replaces the old onException tag.
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.
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.
The ARE officially supports seven kinds of databases. These are the following:
| Database | Purpose | Limitations |
|---|---|---|
| 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.