Introducción a Jade

Departamento de Sistemas Informáticos y Programación, UCM Fecha: 26~3~2003 Profesores: Belén Díaz Agudo, Rubén Fuentes Fernández

Índice.
LA PLATAFORMA JADE. ................................................................................................. 3 CONTENIDO DE LA INSTALACIÓN DE JADE-2.61............................................................. 3 INSTALACIÓN................................................................................................................. 3 ARRANQUE. ................................................................................................................... 4 HERRAMIENTAS DE JADE............................................................................................... 4 IDENTIFICADORES DE AGENTES...................................................................................... 7 PLATAFORMA. ............................................................................................................... 8 AGENTES DE JADE. ........................................................................................................ 8 MANEJO DE ONTOLOGÍAS: ONTOLOGY BEAN GENERATOR. ........................................ 12 ONTOLOGÍAS DESDE JADE ........................................................................................... 12 ÍNDICE DE FIGURAS...................................................................................................... 15

ISBC – Curso 2002/2003

2

La plataforma Jade.
JADE (Java Agent Development Framework) es una plataforma de desarrollo de aplicaciones multiagente conforme a los estándares de FIPA. Ha sido implementado completamente en Java como código abierto. Se compone de dos elementos principales: una plataforma para agentes conformes a las especificaciones de FIPA y un paquete para desarrollar estos agentes en Java.

Contenido de la instalación de Jade-2.61.
Suponemos un PC con sistema operativo Windows y el entorno Java preparado. Si es necesario deberemos ejecutar en la correspondiente ventana del intérprete de comandos la línea:

set PATH=%PATH%;Directorio_Instalación_Java\bin
Los binarios de Jade-2.61 han sido desarrollados con el JDK-1.2 pero también han sido probados con el JDK-1.3. Los ejemplos de este documento se probaron con la versión JDK-1.4.1_01. Se pueden descargar de la dirección http://sharon.cselt.it/projects/jade/. Además es posible obtener en esta dirección los fuentes, documentación y ejemplos de aplicación. En nuestra instalación actual, la máquina tendrá una instalación de Jade en el directorio C:\Jade2.61. Este directorio será referenciado en el resto de l documento como JADE. Colgando del directorio JADE tenemos cuatro subdirectorios: 1. demo. Ejemplo de uso de Jade. Ficheros para la ejecución y de explicación. 2. doc. Documentación de Jade. Incluye la API y manuales de programación, administración, ontologías y seguridad. También hay una explicación de los ejemplos contenidos en el subdirectorio src\examples. 3. lib. Jar de Jade. 4. src. Contiene dos subdirectorios, demo y examples, El primero contiene los fuentes correspondientes al ejemplo en el directorio demo del punto 1. El segundo contiene los fuentes de varios ejemplos más simples con Jade. Los ejemplos siguientes han sido extraídos del administratorsguide.pdf, programmersguide.pdf y CLOntoSupport.pdf.

Instalación.
Para poder trabajar con Jade es necesario hacer disponibles las correspondientes librerías. Los sistemas multiagente se componen de múltiples elementos, los agentes. Aunque en la mayor parte de este tutorial se empleará un IDE gráfico puede ser necesario arrancar agentes desde la línea de comandos. Para hacer disponibles las librerías desde la línea de comandos del sistema operativo hay que hacer:

prompt> set CLASSPATH=%CLASSPATH%;JADE\lib\jade.jar;JADE\lib\jadeTools.jar;J ADE\lib\Base64.jar;JADE\lib\iiop.jar;.
En el caso de un IDE gráfico, nuestro proyecto tendría que tener disponibles las librerías señaladas en la línea anterior jade.jar, jadeTools.jar, Base64.jar y iiop.jar.

ISBC – Curso 2002/2003

3

Arranque.
Los agentes de Jade arrancan dentro de contenedores gestionados por la propia plataforma. A través de estos contenedores se les proporcionan los servicios básicos de ciclo de vida y comunicación. Para arrancar el contenedor principal en modo interactivo empleamos la línea de comandos:

prompt> java jade.Boot –gui
Es posible inicializar contenedores en otras plataformas con la opción host. Para no sobrecargar la máquina con IDE’s es recomendable que al menos la plataforma se arranque desde la línea de comandos. Con el contenedor principal arrancado podemos iniciar agentes con la línea:

java [options] [AgentSpecifier list]
donde AgentSpecifier list es una secuencia de strings separados por espacios. Cada string es de la forma

NombreAgente:ClaseAgente(Argumentos)
donde: NombreAgente es el nombre del agente en la plataforma. ClaseAgente es el nombre cualificado de la clase que implementa el agente. El contenedor cargará dinámicamente esta clase. Argumentos es la lista de argumentos que se pasan al agente en su creación. Un ejemplo con los agentes del directorio examples sería:

Prompt> java jade.Boot –container sender1:examples.receivers.AgentSender
Nota: Los ejemplos son suministrados como fuentes, por tanto es necesario compilarlos previamente. Es posible arrancar los agentes desde la plataforma aunque esto se explicará en el próximo apartado. En algunas instalaciones, la necesidad de la plataforma de establecer comunicaciones con los agentes puede entrar en conflicto con las políticas del sistema. En este caso se hace necesario el arranque de los agentes desde la plataforma.

Herramientas de Jade.
Jade incluye varias herramientas que simplifican la administración de la plataforma y el desarrollo de aplicaciones. Cada herramienta está contenida en un paquete separado de jade.tools. Las herramientas disponibles en la actualidad son: • Remote Management Agent, RMA. Es una consola gráfica para la administración y el control de la plataforma. En la sección Arranque de este documento se indica como iniciar una primera instancia del RMA y su aspecto. Es posible activar varios RMAs. En este caso, Jade mantiene la coherencia entre ellas enviando los eventos a todas. Desde esta consola se pueden arrancar el resto de las herramientas de Jade. Las plataformas aparecen en el RMA con un icono de carpetas amarillas, los contenedores dentro de los RMA’s como carpetas verdes y dentro de los contenedores aparecen los agentes con el icono de cabezas. Para arrancar un agente desde el RMA hay que seleccionar previamente un contenedor. Presionando el botón derecho surge un menú emergente una de cuyas opciones es Start New Agent. Esta opción abre un cuadro de diálogo donde se solicita el nombre del agente, su clase y los argumentos. Siguiendo el ejemplo del apartado anterior, el nombre del agente sería Sender1, su clase examples.Receivers.AgentSender y no tendría argumentos.

ISBC – Curso 2002/2003

4

Ilustración 1. Consola del RMA de Jade en modo interactivo. • IntrospectorAgent. Permite monitorizar el ciclo de vida de los agentes y los mensajes ACL que intercambian.

Ilustración 2. Introspector Agent. • Dummy Agent. Es un agente de monitorización y depurado. Consta de un agente Jade y una interfaz gráfica para el usuario. Permite componer mensajes ACL para otros agentes y visualizar todos los mensajes que envía o recibe.

ISBC – Curso 2002/2003

5

Ilustración 3. Dummy Agent. • Sniffer. Es un agente que intercepta los mensajes ACL lanzados y los visualiza gráficamente en un modo similar a los diagramas de secuencia de UML. Resulta útil para depurar conversacioens entre agentes.

ISBC – Curso 2002/2003

6

Ilustración 4. Sniffer.

Estas herramientas son las empleadas habitualmente en el desarrollo de los sistemas multiagente con Jade. Otras herramientas que también se incluyen son el SocketProxyAgent y el DF GUI que es una interfaz gráfica para el DF (Directory Facilitator) por defecto de Jade.

Identificadores de agentes.
Para realizar comunicaciones entre agentes es necesario que estos estén identificados de forma única en la plataforma. De acuerdo con las especificaciones de FIPA, cada agente posee un Identificador de Agente (AID = Agent Identifier). La estructura del AID se compone de varios campos, siendo los más importante los de nombre y dirección. El nombre del agente es un identificador global único para él. JADE construye dicho identificador concatenando el nombre dado al agente en la plataforma por el usuario con el nombre de la plataforma inicial del agente (HAP = Home Agent Platform) separa dos por el carácter ‘@’. Un ejemplo de este nombre sería peter@kim:1099/JADE, donde “peter” es el nombre del agente y “kim:1099/JADE”el de la plataforma. Sólo los nombres completos son válidos dentro de los mensajes ACL. Las direcciones por el contrario pueden contener varias direcciones de transporte en las cuales contactar al agente. La sintaxis de estas direcciones es una secuencia de URI.

ISBC – Curso 2002/2003

7

Plataforma.
Jade satisface plenamente la arquitectura de referencia de FIPA.

Ilustración 5. La plataforma de Jade distribuida sobre varios contenedores. FIPA incorpora en su plataforma el AMS (Agent Management System) que es el agente que supervisa el acceso y uso de la plataforma de agentes. Sólo existe un AMS por plataforma. El AMS es el encargado de proporcionar los servicios de páginas blancas y de ciclo de vida para los agentes y de mantener el directorio de los AIDs de los agentes y su estado. Cada agente debe registrarse con el AMS para obtener un AID válido. El DF (Directory Facilitator) es el agente que proporciona el servicio de páginas amarillas. El ACC (Agent Communication Channel) es el software que controla el intercambio de mensajes, tanto dentro de la plataforma como con otras remotas. Cuando se arranca la plataforma de Jade, automáticamente se crean un AMS y un DF y se prepara el ACC para manejar mensajes. En cada servidor sólo se ejecuta una JVM. Cada una de estas máquinas es fundamentalmente un contenedor que proporciona los servicios básicos de ejecución a los agentes. El contenedor principal es el contenedor de agentes donde se crean el AMS y el DF y donde se crea el registro de RMI utilizado internamente por Jade. Los demás contenedores conectan con el principal y también proporcionan servicios de ejecución a los agentes.

Agentes de Jade.
Para explicar los principales conceptos manejados por los agentes de Jade vamos a basarnos en los agentes de ejemplo empleados anteriormente (directorio examples/receivers). Definimos un proyecto IRAgents en nuestro IDE y le incluimos las librerías de Jade. Creamos una nueva clase dentro del paquete IRAgents llamada AgentSender que es una instancia de jade.core.Agent. La clase jade.core.Agent representa la base común para todos los agentes de Jade. La herencia de esta clase le proporciona la capacidad de realizar las interacciones básicas con la

ISBC – Curso 2002/2003

8

plataforma (tales como registro o configuración) y para implementar el comportamiento (por ejemplo, el envío y recepción de mensajes o el uso de protocolos de interacción). File AgentSender.java package iragents; import jade.core.Agent; public class AgentSender extends Agent { } El agente tiene un método setup que debe emplearse para la inicialización del agente. Este método se ejecuta después de la inicialización relacionada con la plataforma. Es por tanto aquí donde comienza el comportamiento definido por el usuario. protected void setup() { } Los agentes de Jade se implementan con un único thread de ejecución. Las diferentes tareas que realiza un agente se han de encapsular en comportamientos que heredan de la clase jade.core.behaviours.Behaviour. Para gestionar los comportamientos de un agente la clase Agent tiene los métodos addBehaviour y removeBehaviour. Los comportamientos pueden ser añadido y eliminados en cualquier momento de la vida del agente. Existen varias subclases de Behaviour predefinidas. Los dos métodos principales que debe definir un Behaviour son action y done. Un planificador implementado por la clase Agent y oculto al programador selecciona el Behaviour a ejecutar según un round-robin entre los Behaviour preparados. El Behaviour lleva a cabo su tarea con el método action. El método action es invocado cuando tiene lugar el evento asociado al Behaviour. Este evento puede ser la llegada de un mensaje o una temporización por ejemplo. La aproximación a la planificación hecha por Jade, recomienda que los métodos action no tengan un tiempo de ejecución alto ya que mientras que se ejecutan no pueden ser interrumpidos por otro comportamiento. Cuando termina el método action, se invoca al método done para saber si ha terminado su tarea. En caso de que no haya terminado queda reprogramado para la siguiente ronda. Para poder usarlos añadimos importamos los paquetes: import jade.core.*; import jade.core.behaviours.*; En el método setup añadimos: addBehaviour(new SimpleBehaviour(this) { public void action() { } public boolean done(){ return true; } }); /* Behaviour class end */ El método done de SimpleBehaviour es abstracto por lo que ha de ser sobrescrito. Queremos que el agente sea capaz de enviar una petición a un servidor. Para ello se emplea un lenguaje de comunicación de agentes (ACL). La clase jade.lang.acl.ACLMessage representa los mensajes ACL intercambiados por los agentes. Esta clase contiene una serie de atributos definidos por los estándares de FIPA como emisor, receptor y contenido. Estos atributos pueden ser accedidos por medio de los métodos set/get<Attribute> y add/getAll<Attribute> para aquellos atributos que son conjuntos. Los mensajes son gestionados a través de una cola de mensajes que es única para el agente y, por tanto, es compartida por todos los comportamientos. Añadimos a las importaciones: import jade.lang.acl.*; Para realizar entrada/salida básica añadimos el paquete estándar:

ISBC – Curso 2002/2003

9

import java.io.*; Para enviar mensajes añadimos en el método action del SimpleBehaviour el siguiente código: try{ System.out.println("\nEnter responder agent name: "); BufferedReader buff = new BufferedReader(new InputStreamReader(System.in)); String responder = buff.readLine(); ACLMessage msg = new ACLMessage(ACLMessage.INFORM); msg.addReceiver(new AID(responder)); msg.setContent("FirstInform"); send(msg); System.out.println("\nFirst INFORM sent"); finished = true; myAgent.doDelete(); }catch (IOException ioe){ ioe.printStackTrace(); } Los agentes pueden enviar mensajes mediante el método send y recibirlos con los métodos receive y blockingReceive. El método doDelete es invocado para finalizar la ejecución del agente. Hemos introducido una variable a nivel del comportamiento para controlar la finalización del mismo. Por ello cambiamos el método done a: public boolean done(){ return finished; } Con este código queda completo el cliente. El servidor tiene la misma estructura básica. File AgentReceiver.java package iragents; import java.io.*; import jade.core.*; import jade.core.behaviours.*; import jade.lang.acl.ACLMessage; public class AgentReceiver extends Agent {

protected void setup() {
} } Como comportamiento del agente crearemos una nueva clase cuyo método action es un ejemplo de como descomponer una tarea con una máquina de estados evitando un tiempo de ejecución demasiado largo. El código es: class my3StepBehaviour extends SimpleBehaviour { final int FIRST = 1; final int SECOND = 2; final int THIRD = 3; private int state = FIRST; private boolean finished = false; public my3StepBehaviour(Agent a) { super(a); } public void action() { switch (state){ case FIRST: {state = SECOND; break;}

ISBC – Curso 2002/2003

10

case SECOND:{state = THIRD; break;} case THIRD:{state = FIRST; finished = true; break;} } } public boolean done(){ return finished; } } Para manejar el mensaje que enviará el cliente modificamos el comportamiento. Añadimos un nuevo import: import jade.lang.acl.MessageTemplate; Los agentes han de ser capaces de mantener varias conversaciones simultáneas, sin embargo la cola de mensajes es compartida por todos los comportamientos. Por ello se define la clase jade.lang.acl.MessageTemplate que construye patrones contra los que comprobar los atributos de los mensajes ACL. Estos patrones pueden ser combinados con los operadores AND, OR y NOT. Añadimos un nuevo método op1. private boolean op1(){ MessageTemplate m1 = MessageTemplate.MatchPerformative(ACLMessage.INFORM); ACLMessage msg = receive(m1); El template se pasa como argumento al método receive que lo usa como patrón. if (msg!= null){ System.out.println("\nAgent "+ getLocalName() + " received the following message in state 1.1: " + msg.toString()); return true; } else { System.out.println("\nNo message received in state 1.1"); block(); return false; } } Modificamos el action del comportamiento para que utilice este nuevo método. public void action() { switch (state){ case FIRST: { if (op1()) state = SECOND; else state= FIRST; break;} case SECOND:{state = THIRD; break;} case THIRD:{state = FIRST; finished = true; break;} } } El agente queda completo dando de alta el comportamiento en el agente:

protected void setup() {
my3StepBehaviour mybehaviour = new my3StepBehaviour(this); addBehaviour(mybehaviour); }

ISBC – Curso 2002/2003

11

Para arrancar el ejemplo ejecutaremos desde tres intérpretes de comandos diferentes las líneas:

prompt> java jade.Boot –gui prompt> java jade.Boot -container sender1:iragents.AgentSender prompt> java jade.Boot -container receiver1:iragents.AgentReceiver

Manejo de Ontologías: Ontology Bean Generator.
Un elemento fundamental en los sistemas de agentes son las ontologías. Estas tienen como misión poner de acuerdo a los agentes en el vocabulario con el que comunicarse. Jade proporciona soporte para las ontologías (ver CLOntoSupport.pdf). Las ontologías y sus componentes son traducidos a clases Java que luego son invocadas por los agentes. Construir manualmente las ontologías de este modo resulta muy tedioso. Para automatizar la tarea, la Universiteit van Amsterdam ha desarrollado el Ontology Bean Generator (http://gaper.swi.psy.uva.nl/beangenerator/content/main.php). A partir de una ontología desarrollada con Protégé, el Bean Generator genera las clases necesarias para su manejo desde Jade. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Para realizar la transformación hay que seguir los siguientes pasos: Abrir un proyecto nuevo o existente de Protégé. Incluir el proyecto SimpleJADEAbstractOntology.pprj mediante el menú Project → Include... de Protégé. Crear los conceptos de la ontología como subclases de Concept. Crear los agentes de la ontología como subclases de Agent. Crear los predicados de la ontología como subclases de Predicate. Crear las acciones de los agentes de la ontología como subclases de AgentAction. Ir al menú de Protégé Project → Configure… y seleccionar el checkbox OntologyBeanGeneratorTab. Seleccionar la pestaña del Ontology Bean Generator. Especificar o seleccionar de la lista desplegable el nombre del paquete para la ontología. Especificar o seleccionar el directorio donde serán volcadas las clases java que traducen la ontología. El directorio debe existir. Presionar el botón Generate.

Ontologías desde Jade
En esencia, el soporte que proporciona Jade para las ontologías permite trabajar con ellas en el modo reflejado en la figura.

ISBC – Curso 2002/2003

12

Ilustración 6. Conversión realizada por el soporte de Jade para ontologías. El soporte de Jade para ontologías incluye las clases para trabajar con estas y con los lenguajes de contenido. Los lenguajes de contenido tienen que ver con la representación interna del contenido de los mensajes ACL. Las ontologías tienen que ver con la semántica de los mensajes que se intercambian y su chequeo. Jade incorpora en el paquete jade.content soporte, codecs, para dos lenguajes de contenido. El lenguaje SL es legible por los humanos y codifica las expresiones como string. El lenguaje LEAP no es legible por los humanos y es byte-encoded. El uso de una ontología generada por Protégé desde Jade requiere incluir la librería beangenerator.jar. Para que un agente de Jade use una ontología debe importarla y registrarla. Luego la utilizará con la API correspondiente de Jade. En primer lugar hay que importar los paquetes de soporte de Jade y las clases Java que representan la ontología. En nuestro caso la ontología es ucm.dsip.ontology.Viviendas: import import import import jade.content.lang.*; jade.content.lang.sl.*; jade.content.onto.*; ucm.dsip.ontology.*;

Para almacenar en el agente los datos de la ontología y los codecs definimos dos atributos y los inicializamos: private Codec codec = new SLCodec(); private Ontology ontology = ViviendasOntology.getInstance(); Con los atributos inicializados queda por asociar la ontología y el codec con sus nombres. Esta asociación se realiza a través del ContentManager que forma parte del soporte de Jade para las ontologías. Las instrucciones a emplear son: getContentManager().registerLanguage(codec); getContentManager().registerOntology(ontology); que incluiremos en el método setup del agente.

ISBC – Curso 2002/2003

13

Como ejemplo de uso vamos a modificar el AgentSender para que envíe como contenido de su mensaje un string que el AgentServer comprobará si forma parte del vocabulario de la ontología. Para nuestro ejemplo emplearemos el concepto Piscina de la ontología. Comenzamos modificando el método action del SimpleBehaviour del AgentSender. Sustituimos la línea donde se establece el contenido del mensaje por: msg.setContent("Piscina"); En el AgentReceiver debemos insertar las líneas que vimos previamente para registrar la ontología de Viviendas. Los conceptos de la ontología son representados por Schema. Para obtener el Schema asociado a un string usamos el método getSchema de la ontología. Los Schema son implementados por las clases Java generadas para la ontología. El modo de obtener un objeto Java asociado a un Schema es con el método toObject de la ontología. El código para buscar el concepto asociado al contenido del mensaje en la ontología quedaría en el método op1 como sigue: try { if (ontology.getSchema(msg.getContent()) != null) { Class contentClass = ontology.toObject(ontology.getSchema(msg.getContent()).newInstance()).getClass(); System.out.println("\nConcept " + msg.getContent() + " has Schema " + ontology.getSchema(msg.getContent()) + " which is represented by Java class " + contentClass.getName() + "\n\n"); } else System.out.println("\nConcept " + msg.getContent() + " is not in the ontology.\n\n"); } catch(OntologyException e) { System.out.println("st.nextToken() unsuccessful"); } El uso de las ontología de Jade genera excepciones OntologyException que es necesario tratar.

ISBC – Curso 2002/2003

14

Índice de figuras.
Ilustración 1. Consola del RMA de Jade en modo interactivo. ......................................... 5 Ilustración 2. Introspector Agent. ..................................................................................... 5 Ilustración 3. Dummy Agent. ............................................................................................ 6 Ilustración 4. Sniffer. ........................................................................................................ 7 Ilustración 5. La plataforma de Jade distribuida sobre varios contenedores. ................... 8 Ilustración 6. Conversión realizada por el soporte de Jade para ontologías................... 13

ISBC – Curso 2002/2003

15