miércoles, 31 de octubre de 2007

sumar valor a una fecha

Una de las muchas complicaciones de la programación en JAVA es la programación de fechas. En mi proyecto necesito incrementar el valor de una fecha para trabajar con periodos de tiempo.
El uso de fechas no es trivial, requiere mirar mucha documentación y aprender de ejemplos para no cometer fallos. Y mirando por la red, esta vez si, he encontrado una solución.

Basta con crear un objeto jade.util.Calendar y añadirle valores posteriormente, para luego añadirle un incremento, más o menos siguiendo estas lineas:

String [] dataTemp;
DateFormat df= new SimpleDateFormat("dd/MM/yyyy");

dataTemp= _data.split("/");
Calendar c= Calendar.getInstance();
c.set(Integer.parseInt(dataTemp[2]), Integer.parseInt(dataTemp[1])- 1, Integer.parseInt(dataTemp[0]));
c.add(Calendar.DATE, incremento);

siendo incremento el valor que quiero sumar, en este caso, al día de la fecha (se indica o Calendar.MONTH o Calendar.YEAR si se incrementa el valor del mes o del año, respectivamente).
Con el método set(int, int, int), introduzco al Calendar los valores de año, mes y día, por este orden (fijaros que al valor del mes lo decremento en uno, porque Calendar trata los meses desde 0 a 11).
He podido comprobar, también, que al sumar un incremento que pueda dar un valor superior al valor máximo de un mes, el valor del mes también se incrementa, por sí solo, dando lugar a una fecha correcta.

jueves, 25 de octubre de 2007

... y manejar componentes a la vez

El uso de Thread, del que hablo en el anterior mini artículo, lo aplico a controlar algoritmos que se ejecutan en los formularios de la aplicación cliente. Y al crear un hilo distinto, y toquetear componentes del formulario lleva a un conflicto.
Existe un primer hilo de ejecución (¡supongo que anda por ahí!, o al menos eso dice el compilador) que retiene el funcionamiento de los componentes y no deja que otros hilos modifiquen el estado de éstos. P.ej. desde un segundo hilo quiero escribir cosas a un listBox que tiene el formulario, la ejecución falla.
Y para subsanar está pequeña herida hay que utilizar el código siguiente:

//en los atributos del formulario
delegate void metodoCallback(parámetros);
...
public void recomendation()
{
metodo(parámetros)
}
public void metodo(parámetros)
{
if (this.listBox1.InvokeRequired)
{
metodoCallback process = new metodoCallback(metodo);
this.Invoke(process, new object[] { parámetros });
}
else
{
this.listBox1.Add(parámetros) //por ejemplo
}
}

Aquí, yo quiero llenar una lista, así que la lleno en la condición else del método. Todo lo demás es para hacer que este método manipule el contenido del listBox.
Cómo no he investigado más a fondo para entenderlo; sólo he buscado resultados, no puedo ofreceros una explicación más detallada. No es parte fundamental de mi proyecto así que esto ya sirve.

miércoles, 24 de octubre de 2007

varias tareas... (usando Threads)

Parte de la programación del proyecto se centra en seguir un diseño cliente/servidor. La parte cliente, implementada en c#, es la encargada de enviar peticiones y recibir resultados. Las peticiones son mensajes para obtener datos de una base de datos.
El proceso que debe ejecutar el cliente es largo: incluye varios envíos y recibimientos, por lo que no quiero que se quede bloqueado a la espera de que acabe dicho proceso (no es un requerimiento indispensable para el proyecto, pero ¡me picaba el gusanillo!)

He estado probando implementaciones, consultando de aquí para allá para utilizar Thread en c#, y quiero dejar parte de lo que he estado aprendiendo.
Cuando se inicia el proceso, el código del botón que lo pone en marcha ejecuta lo siguiente:

using System.Threading;
...
Thread hilo =
new Thread(new ThreadStart(recomendation));
hilo.name = "hilo";
if (!hilo.IsAlive)
{
hilo.Start();
}

Al constructor del Thread se le pasa un parámetro, que es el nombre del método que ejecutará, siendo:

private void recomendacion()
{
//lógica del algoritmo
...
hilo.Abort();
}

un método que ni lleva parámetros ni devuelve ningún valor. El código de este método será el que ejecute el hilo recientemente creado.
Y así puedo toquetear otras tareas de la aplicación, mientras el proceso está en marcha. Fijaros que añado el método Abort(). Lo llamo nada más acabar el proceso que ejecuta el método, para terminar el Thread. Este método lanza una excepción System.Threading.ThreadAbortException que no cojo porque no es necesario.

martes, 23 de octubre de 2007

PFC: seguimiento de la comunicación

El agente software se comporta a modo de hilo de ejecución o Thread. Sabiendo esto, uno se puede imaginar que seguir el camino por dónde pasa el código es un poco difícil, debido a su carácter concurrente, que no se sabe si ha pasado por aquí, si está interrumpido... y más si aportas al Thread una autonomía a base de estados, que si active, wait, suspended, running, blocked - los tres primeros estados pertenece a la clase Agent y los dos últimos a la clase Behaviour -.

Habéis leído que para ejecutar código java con agentes hay que escribir en el intérprete de comandos lo siguiente:

java jade.Boot -gui "nombre_agente_1":"clase_java_agente_1"(parámetros)

Fijaros que utilizo la opción -gui. Ésta lanza el agente RMA (Agente de Monitorización Remota o Remote Monitoring Agent para los cultos) que permite ver que agentes están activos dentro de la JVM. (RMA es un agente con una pantalla gráfica asociada). Desde el RMA se pueden lanzar otro agentes que ayudan a controlar la existéncia de los nuestros.
Uno de mucha utilidad (y que utilizo bastante) es el agente Sniffer. Dicho agente permite monitorizar la comunicación que existe entre los nuestros y el contenido de dicha comunicación. Se puede ver el paso de mensajes de unos a otros aún estando creados y en ejecución, porque el agente mostrará cómo ha sido la comunicación entre ellos; en que dirección se han enviado los mensajes.

viernes, 19 de octubre de 2007

PFC: ... digo main

Ya os hablé que en POA no hay un método main, ni nos hace falta una clase main porque JADE tiene su manera de arrancar una aplicación. Pero ha surgido una cuestión que era necesaria utilizar en mi proyecto fin de carrera. Me he visto en la obligación de implementar unas líneas de código para crear agentes en tiempo de ejecución; es decir, que debo crear agentes por código y no sólo tener varios agentes creados inicialmente, al lanzar la aplicación.

El trozo de código que me permite crear agentes dinámicamente es:

Object[] arguments = new Object[]{"a", "b"};
PlatformController plataforma = this.getContainerController();
AgentController control =
plataforma.createNewAgent("nombre_agente"+ _numero, "paquete.claseAgente", arguments);
control.start();

Cómo parámetros hay que pasar un nombre para el agente (yo añado el parámetro _numero para distinguir a los diferentes agentes que voy a crear), la clase que implementa el código del agente y los argumentos del agente.

Los agentes viven en un contenedor ubicado en la JVM. Con este código se obtiene dicho contenedor, que está creado debido a que al lanzar la aplicación, lanzo también varios agentes que sí quiero que estén siempre activos, mientras el código servidor esté funcionando (esto ya prepara a la JVM para acoger a agentes). Tiene que existir otra solución para poder crear dicho contenedor en la JVM y poder crear agentes desde código. Sospecho que las clases PlatformController y AgentController tiene algo que ver.

jueves, 18 de octubre de 2007

sin imágenes

No darlo todo mascado. Los que leáis este blog se supone que tenéis conocimientos suficientes para entenderlo todo. Y si no lo entendéis se supone que sois lo suficiente despiertos - ¡culos inquietos! - para preguntar, buscar, moveros por la red de conocimiento que existe vía internet para entenderlo todo.

No voy a acompañar ningún mini artículo con imágenes. Me gusta la plantilla utilizada para el blog y creo que incluir imágenes le va a quitar el encanto. Sin embargo, si que voy a enlazar imágenes. Que no quiera incluir dibujos en los escritos no significa que no se puedan ver, a razón de ayuda visual para cada escrito.
Dejémoslo así entonces, cómo si cada mini artículo estuviera escrito como si de un manuscrito se tratara; tiene un toque antiguo que favorece la lectura y el interés.

PFC: dónde digo Boot ... (con Eclipse)

Sin irme del proyecto que tengo entre manos, cómo escribo en JAVA gracias al editor Eclipse, deciros que no puedo (o no quiero) ejecutar los agentes desde intérprete de comandos tal y como describo en el mini artículo anterior. Surge la pregunta: ¿cómo ejecuto mis agentes desde Eclipse?

Abrid las propiedades de Run o Debug desde Run>Run o Run>Debug, o desde los iconos correspondientes. Cread una nueva configuración a modo de Java Application. En la pestaña Main, opción Main class escribid jade.Boot y activad la casilla que activa (valga la redundancia) la opción de incluir librerías cuando se busque la clase main.
Id a la pestaña Arguments. En la casilla Program arguments escribid los agentes que deseéis que se ejecuten, de igual modo que habéis leído en el mini artículo anterior.

Con estas instrucciones tenemos una configuración de Run o Debug lista para ejecutar y lanzar nuestro código con agentes.

PFC: dónde digo Boot ...

En una POA, uno debe de olvidarse del main. No existe el tratamiento secuencial de una aplicación: ahora creo la clase, luego hago el cálculo y sigo. ¡No! Nos encontramos ante un tratamiento concurrente, una ejecución en paralelo de algoritmos - algoritmos secuenciales o concurrentes, dependiendo de la lógica de cada aplicación - y cada agente se comporta como un programa independiente que se comunica con otros programas independientes. Aún así, JADE nos proporciona una clase que lleva un método main encargado de dar vida a los agentes: jade.Boot.

Con esto, me ha surgido una duda. ¿Si debo tener varias tareas ejecutándose (cada agente tiene una tarea diferente) cómo ejecuto la aplicación si no hay una clase con un main?
La respuesta es tan sencilla como escribir el nombre de todos los agentes que se haya implementado, a razón de parámetros de la instrucción java, en el intérprete de comandos . Algo cómo:

java jade.Boot -gui "nombre_agente_1":"clase_java_agente_1"(parámetros) "nombre_agente_n":"clase_java_agente_n"(parámetros)

Lo que va entre paréntesis son los parámetros que se le puede pasar a un agente, separados por un espacio en blanco. Desde código se recogen con el método:

Object[] getArguments()

de la clase jade.core.Agent

miércoles, 17 de octubre de 2007

PFC: para usar JADE

Antes de seguir con el mundillo de la implementación de agentes, seguro que preguntais qué IDE utilizo para desarrollar en JAVA. Deciros que utilizo Eclipse cómo editor de código. A otra posible pregunta que se os pasa por la cabeza, que responde al título de este mini artículo, deciros, de manera resumida, que basta con añadir las librerias de JADE al proyecto. (No hay enlace directo a la página de descarga. Debeis registraros con e-mail y contraseña y se os permitirá descargar todo el paquete de .jar; descargar la última versión. Yo trabajo con la 3.5 del 25/06/2007)

Eclipse permite gestionar carpetas del proyecto creado, así que es recomendable crear una carpeta lib, como subcarpeta del proyecto, para guadar ahí los .jar adicionales que se utilizen para el proyecto. Descomprimir el .zip que acabis de descargar y guardar los .jar dentro de esa carpeta lib - los .jar que se necesitan son: http.jar, iiop.jar, jade.jar y jadeTools.jar -

Luego, id al menú Project>Properties, elegid la opción Java Build Path y, en la pestaña Libraries, hay la opción de añadir .jar locales o .jar externos. Cómo los tenemos en la propia carpeta lib del proyecto, nos basta con la primera opción (si los quereis agregar desde otra ubicación, ningún problema). Buscadlos y se puede hacer una selección multiple para no tener que añadirlos uno por uno.

Ya tenemos los .jar de JADE listos para utilizar. Ahora toca leer las API que acompañan al .zip antes descargado y escribir los import pertinentes en cada clase agente a implementar.

PFC: POA

De lo que he podido entender de la documentación que he leído acerca de agentes, y acerca de JADE, un agente es un objeto que actúa siguiendo uno o varios comportamientos. A un objeto Agent se le añaden objetos Behaviour los cuales llevan programado la lógica de un algoritmo concreto.
El agente, cuando nace - los vamos a tratar como seres - llevan a cabo una... puesta a punto con la cual se registran en un directorio virtual de nombres y recogen información del entorno para llevar a cabo su funcionamiento

public class Jane extends Agent
{
...
protected void setup()
{
Object[] args = this.getArguments();
...
DFService.register(this, new DFAgentDescription());
...
addBehaviour(new Smart(this));
...
}
...
}

Por si sólo, el agente no hace nada, solamente existe en la JVM (Java Virtual Machine). Para que haga algo debe llevar asociado algún comportamiento como un SimpleBehaviour o un CyclicBehaviour: ejecutándose una sola vez durante la vida del agente o ejecutándose repetidamente, respectivamente. En código, y de manera esquemática seria algo cómo:

public class Smart extends SimpleBehaviour
{
...
public void action()
{
//lógica del algoritmo que se debe ejecutar
}
public boolean done()
{
//¿ha terminado?
}
}

Como un agente lleva asociados comportamientos que debe utilizar - la clase Agent puede tener varios Behaviours, en la jerga se dice que contiene un pool de Behaviour- se pueden implementar dentro de la clase Agent que hayamos creado, o cómo clase externa, en su correspondiente fichero
El método action() es el encargado de ejecutar los pasos del comportamiento del agente, mientras que el método setup() se encarga de inicializar variables de estado que pueda usar un agente.

Con esto, y sabiendo que un agente se comporta como un Thread - siempre está ahí hasta que lo matas o muere por algún fallo - el estilo de programación cambia bastante. De usar simples clases controladoras, por las que pueda pasar el flujo importante de una aplicación y se ejecutan de manera secuencial, podemos tener varios objetos Agent y ejerciendo el control de la aplicación o código servidor o como gusten. Pasamos a desarrollar una POA o Programación Orientada a Agentes.

martes, 16 de octubre de 2007

primer objetivo: PFC

Empiezo una serie de breves artículos/escritos acerca de mi PFC (Proyecto Fin de Carrera).
Para los que leáis mis delirios psicológicos, el viaje que ahí describo se basa en el transcurso de mi vida diaria desde el punto de vista de este proyecto.

Toca investigar y desarrollar la parte con más chicha del proyecto. Y para empezar debo aprender cómo utilizar agentes software y aplicarlos en él.
De bote pronto podría decir que, con aprender la teoría de threads, tener conocimientos en POO (Programación Orientada a Objetos) y saber utilizar el lenguaje de programación JAVA, uno podría implementar su particular sistema de agentes. Pero cómo no hace falta indagar tanto en este mundillo, voy a utilizar JADE.

De lo que he leído hasta ahora sobre JADE, puedo decir que el uso de agentes software se basa en utilizar clases programadas en JAVA.
Un agente no es más que un objeto, que lleva programado unas operaciones que ayudan a comprender, mediante su uso, el comportamiento de un agente. Ya empecé a escribir algo en la terraza de un club de programación, pero por motivos técnicos (vamos a llamarlos obras en la terraza) voy a continuar el trabajo en este cuarto de derrota, que iré llenando también de otros conceptos.

sitio de trabajo

Existe un espacio reservado para lo personal, un camarote dónde hay espacio para todos los aspectos personales de uno, pensar sobre la vida en sí.
Existe otro espacio reservado para el trabajo. Espacio dónde se experimenta, se estudia, se investiga, se obtienen resultados o productos acabados. Y en todo trabajo de investigación hay una parte de estudio previa, para adquirir conocimientos; hay una parte de desarrollo, para aplicar dichos conocimientos; y hay una parte de documentación, para reflejar qué se ha aprendido y que se ha elaborado.
Toda persona debe trabajar para vivir. El trabajo es lo que nos aporta los beneficios económicos personales que luego emplearemos en gastarlos cómo nos convenga.

Abro este blog para ir escribiendo todo aquello que voy aprendiendo relacionado con el estudio personal. Iré publicando lo que aprendo, para tener un lugar de consulta tanto para mi cómo para la persona que esté interesada.
No sólo con ejemplos se aprende, una explicación acompañante hace mejor su lectura y entendimiento.