Quick link to menu (Bottom of page)

Servidor Web de Carlos Carrascosa Casamayor

JADE (Java Agent DEvelopment Framework) is a software framework to develop agent-based applications in compliance with the FIPA specifications for interoperable intelligent multi-agent systems.

It was developped in Italy jointly by CSELT (Centro Studi e Laboratori Telecommunicazioni) in conjunction with the Computer Engineering Group of the University of Parma . [Note: CSELT is now known as Telecomm Italia Lab (tilab)].


Subclass of the predefined class Agent.

Initial code in the setup method.

import jade.core.Agent;

public class HelloAgent extends Agent {

protected void setup() {

System.out.println("Hello world. ");

System.out.println("My name is " + getLocalName() );



To compile and to execute the above code (HelloAgent.java):

c:\> javac HelloAgent.java

c:\> java jade.Boot fred:HelloAgent

jade.Boot is the class providing the execution environment for a JADE agent.

JADE environments are called containers.

The -gui option creates a Remote Management Agent -RMA- (graphical interface showing all participating agents and containers).

c:\> java jade.Boot -gui fred:HelloAgent

Main Container

There must always exist a main container which mantains a central registry of all containers so that agents can discover and interact with each other. It includes:

Agent Management System -AMS-: keeps track of all JADE programs and agents in the system.

Directory Facility -DF-: yellow page service.

To interconnect various containers, JADE uses the standard Java RMI registry facilities (on port 1099). Options for secondary JADE containers:

-container (to indicate that the container is secondary).

-host (to indicate where is the main container).

-help (The easiest way to get the documentation).

Agent Parameters

On a command line, the parameters are placed in a list separated by spaces after the name:class agent specifier.

c:\> java jade.Boot fred:ParamAgent(3 "Hi there")

The same mechanism is used both to pass arguments from a command line and to pass arguments to agents created by programming.

That command line doesn't work under UNIX or MacOSX. Each agent specifier (name, class & argument list) must be quoted.

The arguments are obtained by calling the method getArguments which returns an array of Objects.


* ParamAgent.java: Retrieving parameters


import jade.core.Agent;

public class ParamAgent extends Agent {

protected void setup() {

Object[] args = getArguments();

String s;

if (args != null) {

for (int i = 0; i < args.length; i++) {

s=(String) args[i];

System.out.println("p" + i + ": " + s);



/// Extracting the integer

int i = Integer.parseInt( (String) args[0] );

System.out.println(" i * i = " + i * i);



Duplicate Agents

A JADE application should have only ONE main-container. Actually, any attempt to start a second main-container on a given machine gives a run-time error.

JADE refuses to create an agent with the same name (case independent) as an existing agent, even in different containers or on different machines. So, only one container can use the -gui option (the RMA agent is given the local name RMA by default), but for instance:

c:\> java jade.Boot -container -host mainHost st3RMA:jade.tools.rma.rma st3:Agent3


In JADE a java thread is assigned to each agent.

Behaviours' purpose is to support efficiently parallel activities within an agent.

A behaviour is basically an event handler, a method which describes how an agent reacts to an event.

Event: Formally, it is a relevant change of state. In practical terms, it is the reception of a message or a timer interrupt.

Agent actions (event handler code) are normally specified in the action methods of Behaviour classes.

Behaviour actions are methods, executed one after the other by the agent's thread after events. They cannot pause without blocking all other activity within the agent.

Behaviour instances are created and linked to the Agent object in the agent' setup method.

import jade.core.Agent;

import jade.core.behaviours.*;

public class myAgent extends Agent {

protected void setup() {

addBehaviour( new myBehaviour( this ) );


class myBehaviour extends SimpleBehaviour {

public myBehaviour( Agent a ) {

super( a );


public void action() {

///<- Real programming goes here!!!


private boolean finished = false;

public boolean done() {

return finished ;


} ///<- End myBehaviour

} ///<- End class myAgent

SimpleBehaviour is the most flexible of JADE's predefined behaviours.

As long as behaviour is not done, its action method will be called repeatedly after every event (receipt of a message, expiry of a timer delay): the finished flag may be used to control when to finish the behaviour (it is tested in the done method and set in the action one).

myAgent: behaviour local variable storing the agent reference passed as a parameter when the behaviour is created.

block( [<delay in ms>] ): takes the behaviour out of the active queue and starts a timer to make it active again after the prescribed delay (the behaviour would also be reactivated if a message were received or the agent restarted). Only the first invocation of block is significant. If block is invoked without any argument, it puts the behaviour on hold until the next message is received, at which time all behaviours wether waiting for messages OR the passage of time (with block(dt) ) will be activated and their action methods called one after the other.

Each agent only has one Thread which is shared by the behaviours. If that Thread is put to sleep (Thread.sleep(dt)), then all activity for that agent stops.

If you don't call block(), your behaviour will stay active and cause a LOOP.

CyclicBehaviour: is a kind of behaviours that stays active as long as its agent is alive.

System.currentTimeMillis(): it returns the current time of the system in milliseconds.

System.exit(0): stops and terminates the program.

Behaviours design considerations

If an activity is made up of a sequence of active phases with pauses in between, the solution is to use several Behaviours, one for every active phase.

doDelete(): Agent method which removes the agent from the system and terminates all its active behaviours.


A fundamental characteristic of multi-agent systems is that individual agents communicate and interact. This is accomplished through the exchange of messages and, to understand each other, it is crucial that agents agree on the format and semantics of these messages. Jade follows FIPA standards so that ideally Jade agents could interact with agents written in other languages and running on other platforms.

There are many auxiliary parts to a message in addition to the content, for example: the intended recipients, the sender and the message type. It is essential for the message as a whole to respect a common format. In JADE, messages adhere strictly to the ACL (Agent Communication Language) standard which allows several possibilities for the encoding of the actual content. In particular, JADE supports FIPA's SL (Semantic Language), a LISP-like encoding of concepts, actions and predicates. It also allows the content to be serialized Java objects.

Structure of a JADE Message

JADE provides get and set methods to access all the attributes of a JADE ACL message:

  • Performative: FIPA message type. The most common ones are:
    • INFORM: one agent gives another some useful information.
    • QUERY: to ask a question.
    • REQUEST: to ask the other to do something.
    • PROPOSE: to start bargaining.
    • AGREE: positive answer.
    • REFUSE: negative answer.
  • Addressing:
    • Receiver
    • Sender (initialized automatically).
  • Content: main content of the message.
  • ConversationID: Used to link messages in same conversation.
  • Language: Specifies which language is used in the content.
  • Ontology: Specifies which ontology is used in the content.
  • Protocol: Specifies the protocol.
  • ReplyWith: Another field to help distinguish answers.
  • InReplyTo: Sender uses to help distinguish answers.
  • ReplyBy: Used to set a time limit on an answer.

When you create a message, you have to indicate its type -its performative- and set the content:

ACLMessage msg = new ACLMessage( ACLMessage.INFORM );

msg.setContent("I sell seashells at $10/kg" );

Sending and Receiving messages

Assuming you have an Agent ID (AID) for the recipient, sending a message is:

AID dest = ...;

msg.addReceiver( dest );

send( msg );

Note: We use addReceiver because there is no setReceiver method. We can add several receivers to the message and one send broadcasts it to all of them.

Receiving messages

  • By using blockingReceive(), the receiving agent suspends all its activities until a message arrives:

ACLMessage msg = blockingReceive();

Optional arguments:

  • pattern object: to select the kinds of message that we want to receive.
  • timeout: if the timeout expires before a desired message arrives, the method returns null.
  • receive() examines the message queue returning a message if there is one or null otherwise. This is the normal technique used when an agent is involved in parallell activities and has multiple active Behaviours.

ACLMessage msg = receive();

if ( msg != null )

<...handle message...>


<...do something else like block()...>

In this way of receiving, a pattern object maybe also considered.

Answering messages

All messages have an attribute which contains the ID of the sender.

ACLMessage msg = receive();

ACLMessage reply = new ACLMessage( ACLMessage.INFORM );

reply.setContent( "Pong" );

reply.addReceiver( msg.getSender() );

send( reply );

createReply(): method that creates a new message with the sender and receiver attributes switched and all other attributes set correctly. Generally, only the content and performative have to be modified before sending it back.

Finding agents to talk to

The problem of how to locate other agents and obtain their AIDs so that we can send them messages.

We can create agent IDs from the agent's local name, for example the one specified on the command line when starting a container. This is specially useful when fixed names for certain agents have been decided beforehand.

The AID constructor takes both a local name and the ISLOCALNAME constant.

ACLMessage reply = new ACLMessage( ACLMessage.INFORM );

msg.setContent( "bla...bla...bla" );

for ( int i = 1; i <= 2; i++ )

msg.addReceiver( new AID( "store" + i, AID.ISLOCALNAME ) );

send( msg );

Other ways to get agent IDs:

    1. Using JADE's GUI interface
    2. From a directory entry in the DF (the normal method).
    3. From the AMS (Agent Management Service) which keeps the IDs of all active agents

Searching the AMS

How to search the AMS to get an array of all presently known agents.

/// Required imports

import jade.domain.AMSService

import jade.domain.FIPAAgentManagement.*;


AMSAgentDescription [] agents = null;

try {

SearchConstraints c = new SearchConstraints();

c.setMaxResults( new Long( -1 ) );

agents = AMSService.search( this, new AMSAgentDescription(), c );


catch( Exception e ) { ... }

The parameters to search include:

    1. the searching agent (this).
    2. An AgentDescription which could be used filter agents
    3. Constraints on the number of agents returned (-1 means ALL).

Comentarios, sugerencias, ...


Take me back to the top.