Actas del II congreso javaHispano

Copyright y permisos de reproducción: los trabajos contenidos en estas actas se hallan bajo la licencia de javaHispano (http://www.javahispano.org/licencias/index.html). En lo relativo javaHispano se permite la reproducción total o parcial de los trabajos siempre que se referencie debidamente el lugar original de publicación del trabajo y a sus autores. Los respectivos autores de cada trabajo pueden imponer restricciones adicionales para su reproducción, por lo que para reproducir total o parcialmente alguno de los trabajos de esta acta javaHispano recomienda contactar directamente con sus respectivos autores.

Editado por Abraham Otero Quintana.

ISBN 84-689-0035-4 Actas del II congreso javaHispano

Actas del II congreso javaHispano

Índice

Prefacio…………………………………………………………………..………………………………....… 5 Comité de Organización……………..………………………..………..…………….…………...... … 6 Comité de revisión…………….…………………..…………….....………………………………...… ..7

Presentaciones invitadas………………….……………………..………………………………...… ..8

Annotation Driven AOP (AOP orientado a anotaciones)..…………………………………………..…...... 9 Alexandre Vasseur Modern Bottom-up Software Composition Techniques: Revisiting Jini, AOP-Style (Técnicas de composición de software modernas, del detalle al concepto: repaso a Jini, con estilo AOP) …………………….………………………………………………………………………..... 10 Hugo Pinto Taming the Tiger (Domesticando al Tigre)…………………….…………………………………………… 11 Neal Gafter y Joshua Bloch Still More Programming Puzzlers (Más soluciones para los rompecabezas de programación)..……. 12 Neal Gafter y Joshua Bloch ¿Has dicho Middleware?...... 13 Miguel Valdes-Faura

Articulos…………………..…………………………………………………………………………….…… 17

SIMToolkit: la última frontera para la integración total, en la palma de tu mano………...... 19 Alejandro Seco Calero y David Fraga Aydillo Aplicaciones de tratamiento de imagen en terminales J2ME con cámara…….…………………..…... 27 Jonatan Tierno Alvite y Celeste Campo Vázquez Programación de dispositivos Bluetooth a través de Java……………………………….…..…….…….. 35 Alberto Gimeno Memoria dinámica en JavaCard: una herramienta para superar las limitaciones…………..…….…... 41 Borja Bravo Alférez y David Fraga Aydillo

JVMTI, Creación avanzada de profilers de aplicaciones con la nueva API de Tiger …………..…...…. 49 Daniel Glez-Peña y Florentino Fdez-Riverola

Actas del II congreso javaHispano

JNIEasy: Aspect Oriented Programming a la ayuda de Java como ciudadano de primera clase en el desktop ……………………………………………………………………………. 57 Jose Maria Arranz Guasaj: Un framework de programación basado en componentes ………………..……….…..... 65 Urko Benito Mateo, Ángel Blesa Jarque y José Javier Lop lis

Extensión del patrón Observador para la integración de eventos de componentes heterogéneos ……………………………………………………………………………………...….…. 73 Luis Rodero, Miguel A. Ortuño y Luis López Seguridad no intrusiva con Acegi Security System for Spring …………………….…..……...…... 79 Carlos Sánchez Estándares libres y Java: ¿Es el JCP un organismo que crea estándares libres?………...……..... 87 A. Otero Integración continua utilizando herramientas Open Source……………………..…………..….... 99 Jesús Perez Caso de uso: Empleo de tecnologías J2EE para el desarrollo de una plataforma para la gestión tecnológica………………………………………………………….....………..….... 107 Rafael Pedraza, Alberto Planas, Antonio Navarro, Benjamín de la Fuente y Jose David Fernández

Actas del II congreso javaHispano

Prefacio

Organizar el congreso hispano independiente sobre Java más grande del mundo no es una tarea fácil. Cuando alguien llega al mostrador de un congreso como este no solo recoge una acreditación de plástico, sino los frutos del trabajo de mucha gente. Un trabajo constante de varios meses al que multitud de personas se han dedicado con un único objetivo: extender el uso de Java en todo el mundo hispano.

Con este mantra en la cabeza desde la organización del congreso, hemos coordinado el esfuerzo de ponentes de varios países de habla hispana. Especial mención y agradecimiento merecen en este apartado las ponencias que hemos recibido de países como Colombia, México y Ecuador entre otros, y que debido a limitaciones presupuestarias y organizativas nos hemos visto tristemente empujados a desestimar en esta edición.

Por supuesto los agradecimientos no se pueden quedar ahí. Esta magnifica reunión hubiera sido imposible sin la gente que habla - nuestros grandes ponentes -, sin la gente que nos apoya - nuestros patrocinadores - y por supuesto sin los que escuchan, asistentes que han empleado sus vacaciones, sus recursos o simplemente su tiempo libre para que todo el esfuerzo del resto de personas no fuera en vano.

Y el resultado de las interacciones de todas estas personas es el que tiene ahora en sus manos. Unas actas que recogen al detalle las diferentes charlas que, siempre siguiendo un riguroso nivel de calidad, exponen diferentes temas de máxima actualidad en el presente. Áreas como AOP, arquitectura, software libre, movilidad y JDK 5.0, todo ello expuesto por ponentes punteros en sus respectivos campos que se han prestado a compartir con todos nosotros sus conocimientos y experiencias.

Y es precisamente ese espíritu de comunidad y el deseo de promover un intercambio de ideas es el que se haya al fin y al cabo detrás de la propia asociación javaHispano. Siempre hemos pensado que la tecnología es una herramienta para construir futuro, que en los países de habla hispana esta requiere de una mayor atención debido al retraso acumulado con respecto a los países anglosajones y que nosotros podíamos hacer algo para cambiar esta situación y convertir al castellano en una lengua que no sea remolcada, sino tractora dentro del campo de la tecnología en general y de Java particular.

Esperamos haberlo conseguido. Al menos hasta la siguiente edición.

Aitor García Rey Pedro del Gallego Vida Presidente del comité de organización Presidente del comité de programa

5 Actas del II congreso javaHispano

Comité de organización

• Presidente: Aitor García Rey. javaHispano, España.

• Alberto Molpeceres Touris, javaHispano, España.

• Álvaro Sánchez-Mariscal Arnaiz, javaHispano, España.

• Martín Pérez Mariñán, javaHispano, España.

• Abraham Otero Quintana, javaHispano, España.

• Isaac Ruiz Guerra, javaHispano, México.

• Enrique Rodríguez Lasterra, javaHispano, España.

• Pedro del Gallego Vida, javaHispano, España.

• Ignacio Brito Calahorro, javaHispano, España.

• Eduardo Millán Martínez, javaHispano, España.

• Emilio Escobar Reyero, javaHispano, España.

• Jesús Navarrete Izquierdo, javaHispano, España.

• Jose Luis Mondelo, javaHispano, España.

• Roberto Andradas Izquierdo, Capítulo de Estudiantes de ACM de la Universidad Rey Juan Carlos

• Álvaro Navarro Clemente , Capítulo de Estudiantes de ACM de la Universidad Rey Juan Carlos

6 Actas del II congreso javaHispano

Comité de revisión

• Presidente: Pedro del Gallego Vida, javaHispano, España.

• Aitor García Rey. Responsable de Proyectos, Grupo AIGE.

• Alberto Molpeceres Touris, Arquitecto Jefe de Software, NHT-Norwick.

• Álvaro Sánchez-Mariscal Arnaiz, Analista, IT Deusto.

• Emilio Escobar Reyero, Analista, ISOTROL SA.

• Ignacio Brito Calahorro, Ingeniero de Software Senior, QualityObjects.

• Isaac Ruiz Guerra, javaHispano, México.

• Jesús Navarrete Izquierdo, javaHispano, España.

• Martín Pérez Mariñán, Arquitecto de Software, DINSA Soluciones.

7 Actas del II congreso javaHispano

8 Actas del II congreso javaHispano

______

______

9 Actas del II congreso javaHispano

10 Actas del II congreso javaHispano

Annotation Driven AOP

(AOP orientado a anotaciones)

Alexandre Vasseur

Abstract Esta ponencia proporciona una introducción a los conceptos de la Programación Orientada a Aspectos (AOP) e intenta explicar cómo las Anotaciones en Java 5 (JSR- 175) y AOP pueden ser utilizados conjuntamente. La ponencia ofrece varios ejemplos de código basados en AspectWerkz, un marco de trabajo de código abierto Java/XML AOP puro.

La primera parte trata de proporcionar un conocimiento básico acerca de los conceptos AOP en general, y cómo dichos conceptos se concretan en código Java, en los que se mejoran las clases regulares con Anotaciones Java 5 y se transforman en aspectos. Se detallan conceptos de Anotaciones predefinidas, proporcionadas por el marco de trabajo para definir nuevas construcciones – exactamente en el caso de los web services (JSR-181).

Las Anotaciones también pueden ser definidas por el usuario y utilizadas en aplicaciones para implementar un comportamiento específico, basado en acceso en tiempo de ejecución a las Anotaciones. El marco de trabajo AOP AspectWerkz soporta coincidencias en esas Anotaciones de propósito específico, de forma que provee de un robusto mecanísmo de coincidencias basado en tipos.

AOP y las Anotaciones no son contendientes sino que se complementan mútuamente y, cuando se utilizan conjuntamente, pueden ser una herramienta muy potente; nosotros creemos que esto va a jugar un papel importante en los futuros desarrollos y estándares Java.

Esta ponencia proporciona una introducción a los conceptos de la Programación Orientada a Aspectos (AOP) e intenta explicar cómo las Anotaciones en Java 5 (JSR- La charla concluye con una explicación de cómo estos conceptos se pueden utilizar hoy en día, y cómo las mismas funcionalidades pueden ser utilizadas gracias a las Anotaciones basadas en Java 1.3/1.4 doclet.

11 Actas del II congreso javaHispano

Modern Java Bottom-up Software Composition Techniques: Revisiting Jini, AOP-Style

(Técnicas de composición de software modernas, del detalle al concepto: repaso a Jini, con estilo AOP)

Hugo Pinto

Abstract En esta charla, Hugo Pinto analiza las tendencias actuales en técnicas de Separación de Conceptos (Separation of Concerns, SoC) basadas en Java(TM), mayormente enfocadas a la descomposición multidimensional (tal como se hace en AOSD), y argumenta que tales aproximaciones, si se aplican a los componentes de sistema además del propio código, amplía enormemente las posibilidades de distribuir y hacer disponible software Java orientado a SOA, muy en la línea de cómo fue propuesto por la Tecnología de Red Jini(TM) en sus orígenes. Hugo establece un paralelismo entre una aproximación Java basada en AOP y Jini 2, y construye el caso en el que se puede crear software con características Jini basándose en componentes de servicio AOP cuidadosamente diseñados, que de esta forma permiten una máxima flexibilidad e interoperabilidad en el diseño de software Java.

12 Actas del II congreso javaHispano

Taming the Tigre (Domesticando al Tigre)

Neal Gafter y Joshua Bloch

Abstract

La reciente aparición de la nueva versión de la plataforma Java (J2SE 5.0, también llamada Tiger) incluye nuevas y excitantes características: generics, enums, autoboxing, for-each, varargs, static import y annotations (metadatos). Unidas, todas estas características incrementan en gran medida la facilidad de programación, mientras que disminuyen la probabilidad de error. Esta charla presenta una introducción a todas las nuevas características, y cuenta cuándo y cuándo no se debe utilizar cada una de ellas. Se proporciona gran cantidad de ejemplos de código.

13 Actas del II congreso javaHispano

Still More Programming Puzzlers

(Más soluciones para los rompecabezas de programación)

Neal Gafter y Joshua Bloch

Abstract

Joshua Bloch y Neal Gafter (también conocidos como "clic and Hack, the Type-It brothers") presentan ocho rompecabezas más para nuestro entretenimiento y aclaración.

El formato de la demostración del juego nos mantiene atraídos mientras que los rompecabezas nos enseñan las delicadezas del lenguaje de programación de Java y de sus librerías fundamentales. Cualquier persona con un conocimiento práctico del lenguaje será capaz de entender los rompecabezas, pero incluso desafiarán a los veteranos más experimentados. Las lecciones ofrecidas en esta ponencia serán directamente aplicables a vuestros programas y diseños. Y algunas de las bromas pueden incluso ser divertidas.

14 Actas del II congreso javaHispano

¿Has dicho Middleware?

Miguel Valdes-Faura

Abstract

15 Actas del II congreso javaHispano

16 Actas del II congreso javaHispano

______

______

17 Actas del II congreso javaHispano

18 Actas del II congreso javaHispano

SIMToolkit: la última frontera para la integración total, en la palma de tu mano.

Alejandro Seco Calero David Fraga Aydillo [email protected] [email protected]

nuestro móvil de bolsillo podemos, a día de hoy, Abstract desde mandar un mensaje de texto, navegar por un buscador de Internet o establecer una EEElEl avance de la tecnología móvil parece no tener frefrenono a día videoconferencia con nuestro colega americano, de hoy. Los terminaterminalesles móviles se renuevan cada menos hasta descargarnos nuestra melodía favorita y todo tiempo y las posibilidades que ofrecen se multiplicanmultiplican de ello lo asumiremos como servicios en su mayor igual manera. En este documento realizaremos un análisis parte habituales. Así pues el término de las posibilidades ofrecidas por tecnologtecnologíasías incluídasincluídas en comunicaciones junto a movilidad van unidos de nuestro móvil como son Java Card (SIMToolkit) y J2ME. La forma irrevocable. tecnologítecnologíaa SIMToolkit nos ofrece la posibilidad de crear en lalala t tarjetaarjeta SIM una aplicación diseñada por nosotrosnosotros,, y El planteamiento desde el punto de vista de usuario realizar desde ella operaciones desde nuestro menúmenú.. P. PorPor de cara a su terminal parece sencillo. Los requisitos otro lado el desarrollo de aplicaciones para J2ME (midlets) fundamentales son interfaces gráficas vistosas, y nos presenta totododo el potencial del API de MIDP tantotanto a funcionalidades cada vez más avanzadas, pero la nivel gráfico como de comunicaciones. Estudiaremos base de todos estos elementos se desarrolla en un oportunidades que nos ofrecen ambas plataformas de cara motor de procesado cada vez más potente. Cada vez a la comunicacicomunicaciónón con el exteriorexterior,, y de igual forma más, el terminal móvil adquiere funcionalidades analizaremos la viabilidad de unir ambos mundos. Las similares a un ordenador convencional, y entre ellas posposibilidadesibilidades que se nos ofrecen son muy amplias, y en hay que destacar las librerías de comunicaciones. base a ellas propondremos líneas futuras y de aplicación. Nuestro sistema va a estar dotado de un amplio abanico de posibilidades a la hora de conectarse al Keywords: J2ME, Midlet, MIDP, GPRS, CSD, JavaCard, exterior. Deberemos tener siempre presente las Smart Card, SMS, evento, proactivo, SIMToolkit(STK). posibles redes de comunicaciones que nos vamos a encontrar: red GSM, red GPRS (sobre GSM), red UMTS, Internet, redes privadas y redes de área 1 Introducción al entorno de aplicacaplicaciónióniónión personal (IrDa, Bluetooth, … ). Hoy en día una de las redes de mayor uso es la red GPRS dimensionada Hoy en día nos movemos cada vez más en un sobre su predecesora GSM. entorno móvil donde los dispositivos de reducido tamaño, inalámbricos, y de altas prestaciones son cada vez más comunes en nuestros bolsillos. Dentro de dicho mundo, no cabe duda, que el gran protagonista en la actualidad es el teléfono móvil.

La ventaja sustancial que nos ofrece la movilidad frente a otros dispositivos no quedaría reflejada si no desarrolláramos convenientemente la capacidad de comunicación entre nuestros terminales. El intercambio de información entre dispositivos móviles es imprescindible a la vez que lógico. Desde Figura 1: Estructura de red GPRS

19 Actas del II congreso javaHispano

Otro factor clave en el mundo de las tecnologías La tarjeta SIM va a ser considerada como un móviles es la tendencia hacia la universalización y periférico adicional dentro de los elementos que estandarización de dispositivos. Los terminales van componen un terminal móvil. La tarjeta adquirirá un a ser desarrollados bajo plataformas muy similares, carácter pasivo. Este rol pasivo se define así ya que de forma que el desarrollo de aplicaciones para cada para que la tarjeta pueda enviar información hacia el uno de ellos sea idéntico y no sea necesario exterior (terminal) recurrimos a un petición de realizarlo y adaptarlo para cada uno. estado continua desde el terminal y en nuestra respuesta desde la tarjeta le indicaremos nuestro Entre las tecnologías que mejor resumen todos los estado junto con la invocación de alguna función a aspectos que se han reseñado encontramos aquellas realizar (comandos proactivos). que se sitúan tanto a nivel de terminal: Java2 ME (plataforma miembro de la familia de productos Java Entenderemos nuestro terminal móvil como un adaptado a terminales o dispositivos de reducido microprocesador (como hemos comentado, tamaño) y Symbian (sistema operativo desarrollado actualmente cada vez son más potentes) con el cual por un consorcio de compañías del sector, el cual interactuamos mediante distintos periféricos, tales permite la programación de aplicaciones por parte como el teclado, el display, audífono o, del usuario), como tecnologías en el ámbito de concretamente, nuestra tarjeta SIM. Por ello cada nuestra tarjeta SIM: Java Card [2] (plataforma de Java uno de estos elementos adquiere gran importancia adaptada para tarjetas inteligentes o smart cards, para la composición final del dispositivo, pero que cuenta con su propia maquina virtual) y, a un especialmente la tarjeta SIM será la que nos permita nivel superior a Java Card, encontramos la interfaz comunicarnos hacia el exterior. Desde la tarjeta SIMToolkit [1], que adapta las posibilidades de una vamos a poder controlar el acceso a la red. La tarjeta SIM al mundo Java. Adentrándonos en el operadora nos va a permitir acceder a sus servicios a mundo de la tarjeta SIM lo que nos ofrece el entorno través de la clave encriptada que reside en nuestra de desarrollo SIMToolkit [1] es la unión de los tarjeta. Así pues tendremos acceso a los mundos de tarjetas inteligentes y nuestro terminal. mecanismos de comunicaciones de nuestra red: Mediante una API propia vamos a ser capaces de SMS, llamadas de voz, llamadas de datos, desarrollar aplicaciones que puedan correr en señalizaciones, etc. No solo se va a poder acceder a nuestra tarjeta, y que posean una interfaz de cara al estos servicios si no además la tarjeta va a disponer usuario en el display del móvil, siendo los aspectos de acceso a información sensible como agenda o visuales opcionales. mensajes, almacenados en la propia SIM

Veamos a continuación la estructura de la familia de Desde el punto de vista del terminal vamos a productos Java 2 , donde aparecen desmarcados en concebir el dispositivo como un pequeño ordenador la parte derecha los productos destinados a desde el que podremos ejecutar aplicaciones dispositivos móviles y smart cards. gráficas, descargar contenidos o conectar con un servidor de correo, todo ello por la capacidad de procesado de la que dispone.

La estandarización de tarjetas SIM parece obvia mientras que por el contrario, a nivel de terminales encontramos en el mercado mucha mayor diversificación. Cada terminal de un fabricante distinto llevará muy posiblemente un procesador diferente pero nos basamos en un de los pilares fundamentales de J2ME, su portabilidad entre distintas máquinas. Todo el desarrollo realizado para nuestra investigación se ha realizado siempre en diversos tipos de móviles encontrando variedad Figura 2 : Plataforma Java 2 de recursos implementados por los mismo, pero manteniendo el núcleo del API de J2ME siempre que

20 Actas del II congreso javaHispano

este estuviera soportado (con su correspondiente cuestión. Tras el envío de un APDU se esperan perfil MIDP) respuestas con un formato concreto y sencillo (Ej, 0x9000 Ok). Será sobre este perfil dónde interactúe Así pues, con todo lo aquí planteado, parece verse STK definiendo un protocolo entre ambos lados. En que delante de nosotros tenemos dos mundos a el cuerpo de los datos enviados en el APDU simple vista diferentes, en primer lugar el lado mandaremos información con cabeceras definidas terminal, y por otro el lado tarjeta SIM. Los dos nos por STK, y de la misma forma en los códigos de ofrecen numerosas posibilidades, y por ello, nuestro respuesta podrá venir información adicional con primer objetivo será el control de ambos campos, formato STK. La comunicación en éste ámbito se va desde la programación básica general hasta el a ver diferenciada por el origen y destino que tenga, control de librería de comunicaciones. Una vez así, diferenciaremos entre mensajes de SIM a alcanzado este objetivo nuestra línea de desarrollo terminal y vicerversa, dando lugar respectivamente, tenderá hacia la unión de ambos entornos, con el fin a los que llamaremos comandos proactivos y de poder procesar información desde un lado y eventos. recibirla en el otro, obtener conectividad desde la tarjeta SIM hacia nuestro terminal móvil y viceversa. Comandos Proactivos

Un comando proactivo es aquel lanzado por la 2 SIMToolkit (STK) tarjeta SIM y cuyo destino es el propio terminal, pidiéndole a éste que realice alguna operación La comunicación entre nuestra tarjeta y el terminal concreta. Existen 31 comandos proactivos posibles móvil se lleva acabo gracias a una API concreta, STK. para poder enviar a nuestro terminal. Los Esta API está estructurada dentro de las normas de dividiremos en 4 categorias: Java Card, por lo que el desarrollo de una applet seguirá el mismo procedimiento que el de una • Applications commands, para desarrollar aplicación en el entorno de tarjetas inteligentes. aplicaciones típicas de STK. Puntualizaremos que para el desarrollo de una • Smart-card commands, destinado a aplicación para Smart Cards deberemos implementar interoperar con otras tarjetas SIM una serie de funciones guión pues el entorno de introducidas en nuestro terminal. ejecución estará predeterminado para buscar estas funciones. Entre estos métodos encontramos: • General communications commands, install(), destroy(), o process(). Métodos que no interfaz para los distintos tipos de vamos a entrar a desarrollar por entender que portadoras soportadas. forman parte del entorno de tarjetas inteligentes y • System Commands, orientados a la salen del contexto de nuestro artículo. Destacar que sincronización con el terminal y la red. una diferencia de STK respecto a Java Card simple es que la primera implementa la función Una vez nos adentramos dentro del bloque de datos processToolkit() , similar a process() en Java Card y del APDU, observamos que los comandos proactivos será ésta la que se ejecute en el momento de están divididos en una nueva estructura. Los activación de nuestra aplicación. bloques que vamos a encontrar dentro del Data load del APDU son denominados TLV (Tag-Length- El formato de transferencia de información desde Values). Cada TLV va a venir definido por un campo una Smart Card (SIM en nuestro caso) recibe el Tag, a modo de identificador, un campo de bytes nombre de APDU. Por consiguiente el terminal móvil indicando el tamaño del siguiente campo, y el también va a esperar recibir este tipo de paquetes campo value, donde encontraremos el verdadero desde nuestra tarjeta. La estructura de un ADPU es valor a nivel de datos. Podremos encontrar varios muy sencilla. Poseen dos campos iniciales, uno de TLV’s concatenados. A modo de ejemplo: podemos clase de instrucción (CLA) y otro de de operación a encontrarnos un Data load en un APDU(SIM->MOVIL) ejecutar (INS), seguidos de dos campos P1 y P2 que donde un primer TLV nos indique el tipo de serán parámetros opcionales, Le (tamaño en bytes proactivo que se envía (Tag = comando proactivo, de la respuesta esperada, Lc (tamaño en bytes del length = 1, value = Display text), un segundo TLV campo de datos) adjunto y el campo de datos en

21 Actas del II congreso javaHispano

indicaría una seria de comandos que no entramos a -La tarjeta como elemento de almacenaje que es, valorar y un tercer TLV nos indicaría qué texto estará compuesta por un sistema de ficheros con queremos sacar por el display. unas características especiales, debido a su limitada capacidad, pudiendo acceder a este sistema de ficheros desde el API de STK (apertura, lectura, Móvil SIM escritura)

–Seremos capaces de poder acceder a los mensajes TLV STK TLV cortos almacenados en nuestra tarjeta y de igual Tag Length Value Tag Length Value manera a almacenamientos de mensajes entrantes en la misma. (recordamos que tendremos manejo CLA INS P1 P2 Lc Data CLA INS P1 P2 Lc Data total sobre mensajes entrantes, evento SMS-PP) APDU APDU Smart Card -Podremos editar y obtener información de las entradas en nuestra agenda personal SIM. Figura 3 : Estructura del APDU -La tarjeta telefónica convencional guarda en Eventos memoria las últimas llamadas de voz realizadas, y Mas allá de poder dar la tarjeta SIM órdenes a de la misma forma podremos acceder a ellas para nuestro terminal a través de comandos proactivos, la comprobar sus destinatarios y duraciones. propia tarjeta podrá registrar una serie de eventos GESTIÓN DE LOS PROCESOS DE COMUNICACIÓN CON que serán lanzados desde el terminal. Entendemos EL TERMINAL este proceso como el paso de información desde el terminal hacia la tarjeta lo cual siempre parece más El planteamiento que acabamos de realizar para el lógico y por ello su mayor facilidad para desarrollo de aplicaciones desde STK (información implementar. Recordamos que la tarjeta adquiere un de la tarjeta) no lleva acabo transferencia de modo pasivo a la hora de poder enviar proactivos información a través de eventos y proactivos. Todo hacia el terminal. Realizando una caracterización de se realiza desde la misma tarjeta la cual obtiene los eventos disponibles según su categoría, información propia, aunque si necesitamos de encontramos los siguientes grupos principales: proactivos para el envío de esta información hasta el display (proactivo DISPLAY TEXT). - Notificaciones de mensajes. Las posibilidades que nos ofrece STK son mucho - Notificaciones de llamadas, y datos. más amplias, y gran parte de ellas tienen que ver - Notificaciones de actividad o selecciones de con las funciones de comunicación de nuestro móvil. menú por parte del usuario. Los tres canales fundamentales de flujo de información (llamadas de voz, SMS y conexiones de - Cambios de estado a nivel de celda datos) podrán ser controlados desde nuestra Entraremos a continuación a valorar posibles aplicación STK. desarrollos y funcionalidades aplicando EL API STK nos ofrece la posibilidad de controlar directamente los conceptos aquí descritos. tanto los mensajes cortos salientes como los entrantes, pudiendo actuar dependiendo de su naturaleza de forma distinta. Existirán dos eventos GESTIÓN DE LA INFORMACIÓN DE LA TARJETA distintos para cada una de las direcciones de envío Como hemos mencionado anteriormente contamos del mensaje (saliente-entrante). Puntualizaremos, en nuestro desarrollo con el API ofrecido por STK. que al igual que todos los procesos anteriormente Este API nos ofrecerá el entorno necesario para descritos, estas funcionalidades quedan fuera de la manejar comandos proactivos y eventos. De la vista del usuario, al cual podremos informarle de las misma forma nos ampliará posibilidades al funciones llevadas acabo a través del display ofrecernos una interfaz Java que nos permitirá únicamente (proactivo que deberemos ejecutar). acceder a la información contenido en la tarjeta SIM:

22 Actas del II congreso javaHispano

Si nuestros mensajes pueden estar bajo control, no DESARROLLOS/APLICACIONES iban a ser menos las llamadas. Tendremos la Veremos ahora algunas de las aplicaciones posibilidad de realizar llamadas a un número realizadas basándonos en toda la estructura aquí concreto, y de tomar acciones a nuestra elección si resumida: una determinada llamada llega a nuestro móvil. MECapabilitiesMECapabilities: El desarrollo de esta aplicación nos Por último destacar la posibilidad de controlar flujos permite obtener una visión completa de las de datos desde nuestro terminal. Los canales funcionalidades implementadas en nuestro terminal, permitidos serán bien CSD o GPRS, determinando en tanto a nivel de proactivos como de eventos. Nos una configuración de parámetros sus respectivas muestra por pantalla el listado completo o calidades de servicios. Seremos capaces por tanto de personalizado de los proactivos/eventos que abrir el canal de datos, obtener información y deseemos consultar y en base a una consulta en el enviarla para posteriormente cerrar nosotros propio móvil nos confirma si está soportado. mismos el propio canal. Reseñamos numerosas dificultades que hemos encontrado en este aspecto Los mecanismos para el desarrollo de esta pequeña en los desarrollos realizamos en el laboratorio por aplicación son muy simples. Basándonos en el motivos de configuración de operador, soporte de evento de acción por parte del usuario (cuando entra transmisión de datos por parte del móvil, y en nuestro menú de aplicación) interactuamos con él configuración adecuada de las calidades de servicio presentándole gráficamente el menú selección desde en el propio canal. el que puede chequear cualquier opción. Desde el API de STK accedemos a la clase ME Profile y desde OTRAS FUNCIONALIDADES allí podremos chequear cualquier tipo de Que nuestra tarjeta SIM soporte JavaCard y evento/proactivo que deseemos. SIMToolkit no implica que el terminal móvil en el que GestSIMGestSIM: Completa aplicación basada en la esté insertada soporte todos los comandos administración, almacenaje y transferencia de proactivos y eventos que están contemplados. Con mensajes y en el control de entradas en la agenda de ello queremos indicar que, cada terminal, la propia tarjeta. Funcionalidades que podemos dependiendo de sus prestaciones nos va a ofrecer la aportar con esta aplicación son, por ejemplo, la posibilidad de interactuar con la tarjeta hasta cierto actualización de contactos de nuestra agenda al punto. Se implementarán por parte de fabricante un llegar a una región distinta donde nuestra empresa cierto grupo de proactivos y eventos a los que posee un grupo de comerciales distintos a la zona responder. Se ha realizado una pequeña aplicación de donde provenimos. Se accede también al control capaz de mostrarnos por pantalla aquellos servicios de llamadas realizadas y salientes, siendo accesibles que el móvil es capaz de procesar. para estas los contactos almacenados en nuestra Una vez planteado que nuestro móvil no tiene tarjeta. A través del manejo de información de porqué implementar todas las funciones, veremos mensajes se pueden obtener funciones de algunas de las más interesantes de cara al localización derivadas de nuestra posición en el programador STK, aparte de las ya vistas: momento de envío.

-Presentación en pantalla de texto, menús, listas y Toda la aplicación se basa en la gestión de los formularios. procesos de comunicación del terminal anteriormente explicados, junto con la interfaz -Respuestas a eventos del usuario: acción sobre gráfico común a todas las aplicaciones de cara al teclas. usuario. -Obtención de parámetro de localización (a nivel de ConGPRSConGPRS: Aplicación aún en proceso de depuración, celdas). que nos permite establecer una conexión de datos a -Obtención de nivel de potencia de las bases más un servidor remoto, enviando información contenida cercanas. en nuestro móvil y cerrando posteriormente todas las comunicaciones.

23 Actas del II congreso javaHispano

Para este desarrollo utilizamos los proactivos tarjetas inteligentes, y entendemos, desde nuestro destinados a canales de datos (clase ‘e’) , y de igual punto de vista, que queda mucho camino por forma presentamos los datos por nuestro display. recorrer para STK, teniendo ya una buena base para empezar a andar.

3 IntegraciIntegraciónón Por último hacer mención al entorno de desarrollo de todo nuestro sistema aquí descrito, y es que por J2ME bajo sus perfiles y configuraciones nos permite muy bien que diseñemos una applet para nuestra el desarrollo de aplicaciones dentro del propio tarjeta SIM, deberemos transferirla e instalarla en la terminal. Estas aplicaciones pueden barajar desde tarjeta. SIMAlliance es la organización que ha interfaces gráficos hasta soporte de comunicaciones estandarizado sus herramientas, de uso público y vía sockets TCP, es por ello que hemos trabajado en con las que recientemente estamos trabajando. Son este sentido para poder explotar especialmente los de fácil acceso, pero al estar poco extendida entre recursos de comunicaciones del móvil. Hemos desarrolladores esta tecnología, las dificultades que realizado implementaciones de aplicaciones cliente- aún se encuentran para el desarrollo no son pocas. servidor vía sockets TCP, vía protocolo http y envío- recepción de datagramas. Hasta la versión MIDP2.0 estas son, junto con https, las implementaciones 5 Líneas futuras posibles de elementos de comunicaciones. No cabe duda que hoy en día la telefonía móvil ha Las plataformas desarrolladas en este artículo (J2ME adquirido un ritmo de crecimiento tecnológico muy y STK) nos ofrecen altas posibilidades de desarrollo alto. Es por ello por lo que movernos de un concepto respectivamente, estando cada una de ellas en tecnológico a otro nos lleva muy poco tiempo y, a mundos distintos a pesar de convivir dentro del día de hoy, la telefonía de tercera generación (3G) propio terminal (móvil y tarjeta). Nos planteamos la está demasiado cerca nuestra como para obviarla. unión de ambos mundos con las ventajas que ello La adaptación de STK a este nuevo entorno es conllevaría. Realizaríamos la ampliación de cada una necesaria pues todas nuestras tarjetas en breve de las API’s por separado, pudiendo interactuar estarán insertadas en teléfonos capaces de desde nuestro móvil con la tarjeta SIM y viceversa. conectarse a la red UMTS.

Entre los mecanismos para realizar esta integración Orientándonos hacia la integración de STK junto a podemos encontrar por ejemplo la implementación J2ME, dos plataformas que ya empiezan a convivir de protocolos propios que utilizando eventos de en nuestro dispositivos, encontramos vías de captura de llamadas o de mensajes, y de esta forma estudio muy interesantes como el JSR de J2ME, interactuar con nuestra tarjeta. Este planteamiento SATSA. Security and Trust Services API for J2ME es la sería sólo en una dirección de comunicación. especifiación de un paquete de java que puede tener Dejamos al lector discernir sobre posibles formas de mucho que decir en el futuro de estas tecnologías. comunicación desde nuestra tarjeta al terminal. Con un final Release por parte del JCP de Sun, y a tan sólo la espera de su implementación por parte de un fabricante en algún dispositivo, SATSA ofrece 4 Conclusiones vías de comunicación a nivel APDU desde nuestro Dos mundos tan aparentemente separados, pero tan terminal hasta nuestra tarjeta SIM. Seremos capaces cerca el uno del otro. Siguiendo la línea de la de, realizando la programación de nuestro módulo integración total o parcial de ambas tecnologías Java, realizar ediciones en los mensajes o agenda de observamos las posibilidades que ofrecerían ambas la tarjeta, enviar eventos determinados o realizar un juntas. La implementación, especialmente en STK, a propio protocolo de comunicaciones entre ambos priori puede parecer algo mas difusa que el dispositivos con el fin de acceder a información en desarrollo en J2ME pues en esta última la aportación un momento determinado. Dejaremos en manos del por la comunidad Java en esta es mucho mayor, pero lector analizar y evaluar otras posibles aplicaciones gracias a las normas GSM [5][6], y a la transparencia bajo esta línea de desarrollo. y practicidad de lo que se pretende hacer, resulta muy agradecido el desarrollo de aplicaciones para

24 Actas del II congreso javaHispano

Agradecimientos

Me gustaría agradecer desde aquí a toda la gente del Laboratorio de Sistemas Integrados, perteneciente al Departamento de Ingeniería Electrónica de la Universidad Politécnica de Madrid la ayuda prestada para el desarrollo de todas las investigaciones relacionadas con esta ponencia. Gracias por hacerme salir cada día sonriendo del laboratorio. Especialmente a David, la figura que mejor representa a un tutor cercano, y siempre dispuesto a ayudar, gracias. Va por vosotros.

Referencias

[1] Scott B. Guthery, Mary J. Cronin. Mobile Application Development with SMS and the SIM Toolkit. McGraw- Hill.

[2] Zhiqun Chen. Java Card Technology for Smart Cards. Addison Wesley.

[3] Roger Riggs, Antero Taivalsaari, Mark VandenBrink. Programming with the Java 2 Platform, Micro Edition. Addison Wesley.

[4] Luis Javier Herrera Maldonado. Tutorial de MIDP , Conexión a redes. http://flanagan.ugr.es/J2ME/MIDP/conexion.htm

[5] ETSI TS 101 267 – GSM 11.14 “Specification of the SIM Application Toolkit for the Subscriber Identity Module”

[6] ETS 300 608 – GSM 11.11 “Specification of the subscriber Identity Module”

25 Actas del II congreso javaHispano

26 Actas del II congreso javaHispano

Aplicaciones de tratamiento de imagen en terminales J2ME con cámara

Jonatan Tierno Alvite Celeste Campo Vázquez [email protected] [email protected]

En este trabajo hemos utilizado terminales de la Serie 60 Abstract de Nokia, principalmente el Nokia 6600, y también el

En este documento vamos a estudiar la posibilidad de Nokia 3650. Como lenguaje de programación, hemos realizar aplicaciones de tratamiento de imagen sobre utilizado Java 2 Micro Edition (J2ME). teléfonos móviles con cámara incorporada en J2ME. Esto Uno de los posibles usos de estas aplicaciones es la implica implementar algoritmos que típicamente tienen alta ayuda a invidentes, pues estamos hablando de carga computacional sobre dispositivos limitados en manipular información visual sobre un dispositivo que la memoria y capacidad de proceso, y además sobre J2ME, gente usa en su vida cotidiana. Por ello, hemos que suele ser considerado un lenguaje de programación implementado dos aplicaciones dirigidas a este fin: La poco eficiente, y de posibilidades limitadas dada su primera es un Lector de Colores, que permitirá conocer a reducida API. Hemos realizado dos aplicaciones de ejemplo: un usuario ciego los colores de un objeto al que dirija la Un Lector de Colores y un Detector de Movimiento. Después cámara, por ejemplo, una prenda de ropa. La segunda es hemos realizado un estudio sobre las capacidades de un un Detector de Movimiento, con el que podrá saber terminal concreto, tanto en capacidad de proceso como en cuando alguien entra en una habitación, cuando se la calidad de imagen que podemos obtener. Con estos apaga o enciende la luz, etcétera. datos sacamos conclusiones sobre qué tipo de aplicaciones es posible realizar en estas condiciones y para qué otras es El resto del documento se organiza de la siguiente necesario buscar una plataforma más potente. forma: En la sección 2 vamos a hablar de la Mobile Media API (MMAPI), que es la librería de J2ME que da Keywords: Tratamiento de imagen, teléfonos móviles acceso a la cámara desde un MIDlet, y del acceso a la con cámara, MMAPI, ayuda a invidentes. información de las imágenes de la cámara. Tras esto, se describe la implementación de dos aplicaciones de ejemplo: el Lector de Colores, al que dedicaremos la 1 Introducción sección 3 y el Detector de Movimiento, que se tratará en Hoy en día muchos teléfonos móviles (y algunas PDAs) la sección 4. En una segunda parte del proyecto, pueden obtener información no sólo de las redes de realizamos un estudio de un terminal concreto (el Nokia comunicaciones a las que están conectados, si no 6600), para determinar su capacidad de ejecutar también del entorno físico, mediante grabación de audio aplicaciones de tratamiento de imagen. En la sección 5 y video. hablaremos sobre el acceso a la calidad de las imágenes disponibles, y en la sección 6, sobre la capacidad de Hasta ahora, y centrándonos en la cámara de fotos y proceso y la memoria del terminal. Por último, en la vídeo, esta nueva capacidad se ha utilizado de la misma sección 7 usaremos todos los datos obtenidos para forma que en una cámara convencional: se guarda la discutir sobre qué aplicaciones pueden implementarse fotografía o el archivo de vídeo en el terminal para sobre estos terminales y cuáles no. recuperarla más tarde o para enviarla a otro dispositivo.

En este documento vamos a discutir la posibilidad de 2 Mobile Media API (MMAPI) y el realizar un cierto procesado sobre esa información antes acceso a la cámara de pasar los resultados al usuario. La Mobile Media API (MMAPI) es una librería opcional de J2ME que permite acceder a cualquier tipo de contenido

27 Actas del II congreso javaHispano

multimedia (imágenes, audio, video), tanto local como complicada o incluso inabordable por razones de remotamente. También es el interfaz J2ME hacia eficiencia. grabación de audio y video. El hecho de que sea una librería opcional significa que pueden ofrecerla tanto terminales MIDP 1.0 como 2.0. Sin embargo, aquellos terminales que no dispongan de ella, no tendrán ningún 3 Lector de Colores tipo de acceso Java hacia la cámara. El lector de colores permite a un usuario conocer los La MMAPI consigue tratar diversos tipos de contenidos colores del objeto que esté enfocando con la cámara del de la misma manera mediante un alto nivel de móvil. De esta forma un invidente puede separar la ropa abstracción que esconde las operaciones a bajo nivel que blanca de la de color para hacer la colada, por ejemplo. realiza el sistema operativo. La MMAPI ofrece un interfaz La aplicación está dividida en los siguientes bloques: común a la lectura de datos desde cualquier fuente y en captura y muestreo de los pixels, clustering, decisión y cualquier formato mediante un Identificador Uniforme por último, comunicación de resultados. de recursos (URI), que definirá el dispositivo y los Al inicializar la aplicación, la cámara se pone en parámetros de reproducción. El acceso a la cámara se funcionamiento, y cuando el usuario apunta a un objeto realiza con el URI especial de captura “capture://video”. y pulsa el botón de acción, realizamos la captura y Con la llamada “System.getProperty(String key);” muestreo de la imagen. En este bloque tomamos una podemos saber si nuestro dispositivo permite captura de fotografía mediante el método getSnapshot, y video o no, y en qué formatos. accedemos a los pixels según hemos descrito más arriba. El programador manejará una realización del interfaz De toda la imagen, tomamos una muestra adecuada Player, que creará con un Manager, con la orden “Player para el procesado posterior: 50 píxeles de la parte player = Manager.createPlayer(String uriString);”. Con central de la imagen. La cifra escogida es un compromiso esto, podemos acceder a las imágenes de la cámara entre la información de la imagen presente en la muestra como un flujo de video . Para tomar una fotografía, y el tiempo que tardaremos en realizar el procesado. usamos el método VideoControl.getSnapshot(String Sobre estos pixels vamos a ejecutar el algoritmo de imageType), que nos devuelve un fotograma de ese flujo custering llamado K-medias. El clustering o en el tamaño y el formato que especifiquemos en el agrupamiento consiste en dividir un conjunto parámetro imageType. heterogéneo de elementos en grupos o clusters, de Para que nuestra aplicación pueda obtener información modo que los elementos más parecidos estén juntos. de esta imagen y realizar un procesado sobre ella, Cada cluster está representado por un centroide, que necesitamos acceder a los pixels. MIDP 2.0 ofrece viene a ser el promedio del cluster, por la varianza del directamente esta funcionalidad con el método getRGB() centroide, es decir, la dispersión de los elementos en un de la clase Image. Esta es la solución utilizada con el cluster, y su número de elementos. El K-medias, es un teléfono Nokia 6600 en las aplicaciones que hemos algoritmo simple y rápido que trabaja con un número implementado en este trabajo. fijo de clusters, que en nuestra aplicación serán tres. Esto significa que podremos averiguar hasta tres colores de El teléfono Nokia 3650 es MIDP 1.0 y no disponía de este una imagen simultáneamente. método. Una posible solución era el método “DirectGraphics.getPixels”, de la librería NokiaUI. Sin Para implementar el algoritmo necesitamos definir la embargo esta es un API propietaria y no se encuentra en distancia entre dos colores. Para esto, en primer lugar todos los terminales Java. convertimos los valores RGB de los píxeles a coordenadas HSB (Crominancia, Brillo, saturación), que son más La solución adoptada para el Nokia 3650 fue parsear el adecuadas para comparar colores. La distancia entre dos fichero PNG. En este caso fue bastante sencillo, puesto colores que hemos usado responde a la expresión: que la información no estaba comprimida, y sólo tuvimos que eliminar las cabeceras del fichero. En otros d[(h1,s1,b1),(h2, s2,b2)]= α( h 1-h 2)+β( s 1-s 2)+γ( b1-b2) terminales (por ejemplo, en el Nokia 6600) puede no donde α, β y γ son coeficientes hallados empíricamente darse el caso, siendo entonces esta tarea muy que representan la importancia de cada una de las tres características a la hora de diferenciar dos colores.

28 Actas del II congreso javaHispano

El K-medias es un algoritmo iterativo que precisa una Para detectar el movimiento, simplemente comparamos condición de parada. En nuestro caso, el algoritmo se el color del píxel central de una imagen con el de la detendrá cuando se cumpla cualquiera de dos anterior. Dado existe cierto ruido en la imagen, aún en condiciones: La primera es que se alcance un número dos imágenes representando la misma escena los valores máximo de operaciones, para evitar que el algoritmo se exactos de los pixels cambiarán ligeramente. Esto ejecute indefinidamente. La segunda es que la suma de significa que para detectar el movimiento no basta con las varianzas de los clusters deje de disminuir, lo que ver si los píxeles son iguales. Lo que haremos será medir significaría que más iteraciones no mejoran la la distancia Manhattan entre ellos y compararla con un distribución de los elementos en los clusters. umbral que fijaremos empíricamente. Notificaremos que ha habido movimiento cuando este umbral se supere. En el bloque de decisión vamos a determinar cuales son los colores que contienen los clusters hallados. En primer Para evitar falsas alarmas conviene tener un umbral lugar, debemos averiguar si dos clusters contienen el elevado, sin embargo esto tiene el inconveniente de que, mismo color. Para esto, medimos la distancia entre sus en el caso de que el objeto responsable del movimiento centroides en relación con la varianza de ambos, y sea del mismo color que el fondo, este movimiento comparamos con un umbral hallado empíricamente. pasará desapercibido. Para reducir este umbral sin También debemos decidir si cada cluster contiene pixels aumentar la probabilidad de falsa alarma, usaremos el de un solo color o de varios. Para esto, compararemos hecho de que el ruido es independiente: Cuando se la varianza de los clusters con otro umbral. Con estas produzca un movimiento, lo confirmaremos con los comprobaciones, podemos saber cuántos colores píxeles vecinos, y sólo lo notificaremos cuando el cambio conforman la imagen, y si son más de tres, que es el se halla producido para todos ellos. De esta forma, el número de clusters, emitiremos un mensaje de error. tiempo de proceso se mantiene reducido para la mayoría de las iteraciones. Después de esto, asignamos a cada centroide una categoría de color. Para ello, hemos dividido el espacio Realizando pruebas con el terminal Nokia 6600, HSB en regiones, cada una con un color asociado. Hecho establecemos que con un umbral por debajo de 80, esto, basta con ver en qué región cae el centroide de sobre una distancia máxima entre pixels de 256·3, se cada cluster. producen falsas alarmas. En cuanto a la velocidad de muestreo, es muy reducida. Utilizando el formato BMP, Por último, tenemos que comunicar los resultados al sólo conseguimos llegar a las 2 imágenes por segundo, usuario. Cada región tiene asociado un fichero de audio que es baja para aplicaciones con restricciones de tiempo en que una voz pronuncia el nombre del color. Tras la real en general, pero para este caso puede ser suficiente etapa de decisión, los colores resultantes son emitidos. si no nos encontramos ante cambios muy bruscos. Los más abundantes van primero, de forma que el usuario sepa el color dominante en la imagen. 5 Pruebas de la cámara 4 Detector de Movimiento En este apartado vamos a estudiar las imágenes ofrecidas por la MMAPI en el terminal Nokia 6600, en Esta aplicación muestrea continuamente el flujo de vídeo términos de formatos, resolución, tamaño, número de ofrecido por la MMAPI en busca de movimiento y, colores, y tiempo de adquisición. Este teléfono, así como cuando éste se produce, la aplicación emite un sonido y la mayoría de los de su clase, tiene una cámara VGA, muestra la imagen en que éste se produjo. Esta MIDlet esto es, puede ofrecer fotografías de 640X480 pixels, y simplemente compara una imagen con la anterior en un esta es la resolución que podemos conseguir con la bucle, y de éste si son distintas, sale del mismo. aplicación nativa de la cámara y con programas en La comparación entre dos imágenes es muy simple para Symbian. Hemos hecho medidas de tiempo y tamaño permitir que el bucle sea tan rápido como sea posible, y por los tres formatos disponibles en el Nokia 6600, PNG, que la velocidad esté limitada por la máxima frecuencia a BMP y JPEG (esta información está disponible en la la que la que podemos llamar al método getSnapshot(). variable de sistema video.snapshot.encodings). Por Por esta misma razón, esta velocidad de muestreo puede defecto, el método getSnapshot() devuelve una imagen no ser constante. PNG de 160X120 pixels, pero se puede especificar el formato y las dimensiones en pixels deseados. Hemos

29 Actas del II congreso javaHispano

tomado medidas para cada tamaño y formato, y los alcanza velocidades ligeramente superiores, del orden de resultados se muestran en la Figura 1. También siete imágenes por segundo. comparamos la influencia de la complejidad de la Las imágenes en JPEG son las más pequeñas, y el imagen en el tamaño de fichero: Primero, tomamos una tamaño de fichero es poco dependiente de las imagen de una pared blanca, y luego otra de una escena dimensiones de la imagen, y más de la complejidad de la compleja, con gente y diferentes objetos. Los resultados escena. Las imágenes PNG son mayores, pero es el único se pueden ver el la Tabla 1. formato obligatorio para las especificaciones de la Tabla 1: Influencia de la complejidad de la escena en el MMAPI. El formato BMP no usa compresión, por lo que tamaño del fichero de imagen. el tamaño de fichero es proporcional a las dimensiones de la imagen. Sin embargo, la calidad de imagen es baja, Tamaño (bytes) puesto que usa una paleta de 256 colores para (8 bits PNG Simple 28953 por pixel) para evitar que el tamaño se dispare. Hay que

Compleja 44248 notar que para el tipo de aplicaciones que estudiamos, el tamaño de fichero no es tan importante, ya que nosotros BMP Simple 20278 vamos a trabajar sobre los valores RGB de los pixels, Compleja 20278 luego en todos los casos necesitaremos un array de

JPEG Simple 1223 longitud dependiente de las dimensiones de la imagen. Una vez tengamos este array, podemos liberar la Compleja 3469 memoria que ocupe la imagen. Por otro lado podemos estar interesados en sólo parte de la imagen, así que en cada caso debe estudiarse qué formato es la mejor Cuando el tamaño del fichero es demasiado grande para elección. el teléfono, lo que depende tanto del formato como de 18 las dimensiones de la imagen, hemos observado que PNG BMP JPG pueden ocurrir dos cosas: En ocasiones, la aplicación se 16 bloquea, y la cámara deja de estar disponible hasta que 14 reiniciamos el teléfono. Más a menudo, la aplicación 12 aborta con un mensaje tipo “Application closed Monty Thread –7”. 10

8

Observando la calidad de las imágenes en diferentes TIME (sec.) -> dimensiones, se aprecia que el teléfono siempre utiliza 6 imágenes del tamaño por defecto (160X120), y después 4 los reescala si es necesario. Por tanto, la calidad de la 2 imagen no mejorará. 0 160x120 (default)200x150 320x240 400x300 640x480 800x600 Para aplicaciones de tiempo real, tales como el Detector IMAGE DIMENSIONS -> 800 de Movimiento, podemos ver que no se alcanza una PNG BMP JPG velocidad elevada: En el mejor de los casos, nos 700 acercamos a dos imágenes por segundo (para imágenes 600 del tamaño por defecto). Los formatos más rápidos son

JPEG o BMP, con tiempos similares. Uno podría 500 preguntarse porqué el formato JPEG es el más rápido, 400 cuando es el que requiere un procesamiento más complejo. Se da que una cámara típica para este uso FILE SIZE (KB) -> 300 puede ofrecer varios formatos: Imágenes sin comprimir 200 (YCrCb) o imágenes comprimidas JPEG. De modo que la máquina virtual sólo necesita tratar imágenes PNG o 100

BMP, las imágenes JPEG son creadas por hardware. Los 0 160x120 (default)200x150 320x240 400x300 640x480 800x600 mismos tests han sido realizados para el Nokia 3650 y IMAGE DIMENSIONS ->

30 Actas del II congreso javaHispano

Figura 1: Tiempo de adquisición (arriba) y tamaño de 6.1 Velocidad de operaciones fichero (abajo) para diferentes tamaños en los formatos Primero mediremos la velocidad de operaciones básicas de imagen disponibles. del procesador, y podremos ver cuáles son más rápidas y Algunos de los aspectos que hemos descubierto sobre el cuáles deben ser evitadas al programar. Sólo nos funcionamiento de la MMAPI de Java pueden explicarse referimos a operaciones de bajo nivel: extracción de una conociendo el acceso a la cámara en lenguaje nativo. En variable de un array, suma de dos variables, Symbian, el acceso está basado en imágenes, no en desplazamientos lógicos, etcétera. Sólo hablaremos de video. El viewfinder debe implementarlo el programador este tipo de operaciones porque son las que hay en cada aplicación concatenando imágenes disponibles en J2ME. periódicamente. Las imágenes se obtienen usando un Para medir tiempo, J2ME ofrece el método esquema de objetos activos, y en un formato específico System.currentTimeMillis(), que tiene una precisión de de java, que posteriormente puede convertirse en el milisegundos. Lo que haremos será repetir la operación a formato deseado. Uno de los parámetros de la petición medir en un bucle, restar el tiempo de un bucle vacío, y de la imagen es la calidad, que puede ser alta o baja. dividir por el número de iteraciones. Hemos Una imagen de baja calidad (llamada snapshot), es implementado un programa que realiza estas medidas y QQVGA, es decir, de dimensiones 160X120 pixels, y de muestra el resultado por pantalla. Las medidas estarán 4096 colores (12 bits por pixel). Una imagen de alta distorsionadas por otros procesos concurrentes del calidad es VGA (640X480) y de 16 millones de colores teléfono, como la lectura de eventos de teclado u (24 bits). Típicamente, las snapshots se usan para formar operaciones relacionadas con el servicio telefónico. De el viewfinder y video, y las imágenes VGA para la hecho, si durante la ejecución del programa presionamos fotografía propiamente dicha. Además, el programador teclas repetidamente, se aprecia un incremento del puede elegir entre dos perfiles de iluminación, noche y tiempo. No intentaremos evitar estas distorsiones, día, lo que modifica el brillo de la escena por medio del simplemente tomaremos varias medidas y calcularemos balance de blancos. la media. Los resultados obtenidos se muestran en la tabla 2. Con esta información, podemos inferir que el MMAPI crea el flujo de vídeo por medio de snapshots tomadas Con estos resultados podemos inferir que la división periódicamente, y los pasa a la aplicación. Las imágenes debe ser evitada en la medida de lo posible, y que no obtenidas con getSnapshot() son simplemente uno de debemos abusar de la multiplicación, debiendo sustituir estas snapshots, reescalada y con un formato diferente si ambas por desplazamientos lógicos cuando sea posible. es necesario. Por tanto no podremos acceder desde un Vemos que, sorprendentemente, las comparaciones son MIDlet a la calidad de imagen que la cámara puede también lentas, incluso más que la multiplicación El ofrecer. acceso a una variable de un array es más lento que una suma porque usa indirección.

6 Velocidad de operaciones y memoria Hay que decir también que las operaciones deben usar números enteros. Si es necesario utilizar decimales, lo Para implementar aplicaciones de tratamiento de adecuado es recurrir a la llamada aritmética de punto imagen, nuestro terminal debe ser capaz de ejecutar fijo, que permite cálculos decimales usando tipos algoritmos pesados rápidamente, en ocasiones en enteros. tiempo real, y también necesita almacenar la información de los píxeles de una o varias imágenes. El teléfono Nokia 6600 utiliza un procesador ARM de 32 Según esto, la velocidad de las operaciones y la memoria bits a 104 MHz, lo que hace un ciclo de reloj de dinámica disponible son características claves para aproximadamente 10 nanosegundos. Típicamente, una nuestros objetivos. operación simple de procesador tarda dos ciclos de reloj, esto es, 20 nanosegundos, lo que nos deja cerca del tiempo medido para las operaciones más rápidas.

31 Actas del II congreso javaHispano

Esto nos podría hacer pensar que, si las operaciones van en las pruebas que acabamos de realizar en particular. a la velocidad del procesador, entonces un MIDlet También se da que los algoritmos de procesamiento de correrá tan deprisa como una aplicación Symbian, lo cual imagen son frecuentemente iterativos, con lo que la no parece lógico. La explicación es que la máquina suposición se cumplirá también para las aplicaciones virtual del Nokia 6600, llamada Monty 1.0 VM, utiliza un bajo estudio. Esto significa que podemos esperar un esquema de compilación dinámica. Esto significa que la buen comportamiento de nuestros MIDlets respecto a las máquina virtual tiene, además de un interprete (que aplicaciones nativas. ejecuta bytecodes de Java), un compilador (que convierte bytecodes en código nativo). 6.2 Memoria dinámica

El código nativo es alrededor de un orden de magnitud A continuación hablaremos sobre la memoria dinámica más rápido que el interpretado, pero ocupa pero ocupa de la que disponemos. La memoria volátil que se dedica más memoria. La Monty VM soluciona esto con un al almacenamiento de objetos Java se denomina heap. bloque más llamado Profiler, que identifica, en tiempo Según las especificaciones, el Nokia 6600 dispone de una de ejecución y mediante métodos estadísticos, partes del heap de 3 Mbytes. Para comprobar esto, utilizamos una código que el MIDlet ejecuta a menudo y repetidamente. aplicación nativa llamada Fexplorer, que permite navegar Estas partes del código se denominan hotspots. Cuando por los archivos del teléfono, así como saber la memoria el profiler identifica un hotspot, éste se compila de libre del dispositivo. Con esta aplicación descubrimos forma que las siguientes veces que el MIDlet llame a esta que la memoria dinámica libre, independientemente de parte del código se pueda ejecutar directamente en los datos almacenados en la memoria flash, es de 10 código nativo. El resto del código, accedido menos a Mbytes. Sin embargo, la heap podría ser menor al ser la menudo, es ejecutado por el intérprete. memoria disponible para MIDlets.

Para comprobar esto, y tomar medidas reales, Operación Duración Una operación implementamos una MIDlet que intenta reservar bucle (ms) (ns) memoria del tamaño que se le especifique. La Bucle vacío 1 372.0 0.0 ejecutamos varias veces con tamaños crecientes, y vimos

Extracción de un 2 062.7 69.1 en qué punto aparecían excepciones del tipo Out of array Memory Error. Si la memoria se reserva nada más iniciar la aplicación, alcanzábamos los 700 kilobytes. Sin Incremento 1 573.3 20.1 embargo, si esta memoria se liberaba y se reservaba más (++) sin salir de la aplicación, y se incrementaba esta cantidad poco a poco, alcanzábamos varios megabytes, por Suma 1 565.9 19.4 encima de la heap indicada en las especificaciones del Desplazamiento 1 562.5 19.1 teléfono. lógico Con estos experimentos, podemos concluir, primero, que la heap que puede alcanzar un MIDlet es de 10 Multiplicación 1 862.6 49.1 Megabytes, y no de 3. Y segundo, que la memoria División 12 396.7 1 102.5 asignada a un MIDlet es dinámica: inicialmente, la Menor o igual 2 375.1 100.3 máquina virtual permite una pequeña cantidad, pero cuando la memoria realmente usada por el MIDlet se Menor 2 351.4 97.9 acerca al límite, se le asigna más. Igual 2 554.8 118.3 7 Lo que podemos y no podemos Tabla 2: Duración de un bucle de 10 000 000 iteraciones hacer y de una sola operación. Promedio de diez medidas. Una primera conclusión es que la primera acción a La compilación dinámica se basa en la suposición de que realizar al abordar una aplicación de este tipo, es los programas ocupan la mayor parte del tiempo identificar los recursos de que disponemos desde J2ME, ejecutando una pequeña parte del código. Ésta ya que pueden no ser los mismos que desde una propiedad suele cumplirse con el software en general, y

32 Actas del II congreso javaHispano

aplicación nativa o que los que permitiría el hardware MMAPI que permitan obtener el máximo provecho de las del teléfono: que el terminal tenga cámara no significa características de la cámara. Sin embargo, incluso con las que sea accesible desde Java, y que ésta sea VGA no capacidades de los terminales estudiados, pueden significa que podamos sacar fotos de 640X480, etcétera. implementarse aplicaciones novedosas y útiles mediante un diseño cuidadoso y una buena dosis de creatividad. De acuerdo con los resultados obtenidos, el límite mayor lo impone la cámara, o más exactamente, las imágenes que ofrece la MMAPI a los MIDlets. El pequeño tamaño Referencias de las imágenes, combinado con la falta de un [1] Especificaciones del terminal Nokia 6600. Forum Nokia mecanismo de enfoque, que impide tomar fotografías http://www.nokia.com/nokia/0,8764,33211,00.h nítidas de objetos a menos de 20 cm de la cámara, hace tml. difícil implementar aplicaciones como lectores de [2] Especificaciones del terminal Nokia 3650. Forum Nokia http://www.nokia.com/nokia/0,8764,2275,00.ht códigos de barras, reconocimiento de texto, etcétera. ml. Con una aplicación nativa podemos alcanzar una mayor [3] Programming Wireless Devices with the Java 2 Platform, resolución, aunque el problema del enfoque sigue Micro Second Edition. Roger Riggs (Editor), Antero presente. Taivalsaari, Jyri Huopaniemi, Mark Patel, James VanPeursem and Aleksi Uotila. Addison-Wesley Pub Co; 2 Si nuestra aplicación necesita procesado de tiempo real, Edition. June 2003. de nuevo J2ME ofrece muy pobres prestaciones, [4] Brief Introduction to the Mobile Media API. Forum Nokia, Version 1.0. 2003. mientras que Symbian ofrece una velocidad de muestreo [5] Nokia UI extensions for Nokia MIDP Platform. Forum Nokia, que bastará en la mayoría de los casos. Version 1.1. 2002. Si las aplicaciones tienen suficiente calidad y velocidad [6] Developing Series 60 applications: a guide for Symbian OS C++ developers. Leigh Edwards and Richard Barker. con lo ofrecido por la MMAPI, encontrarán el límite Addison-Wesley. 2004. impuesto por la velocidad de operaciones, y también con [7] The Project Monty Virtual Machine. la reducida API de matemáticas ofrecida por MIDP. White Paper. 2002. Respecto al primer punto, según discutimos antes se [8] What Color Is Your Pair of Shoes? A Review of Two Color puede esperar un comportamiento razonablemente Identifiers. Deborah Kendrick. Access World, vol. 5, no. 3, May 2004. http://www.afb.org/aw. similar entre aplicaciones Symbian y J2ME. Respecto a las funciones matemáticas disponibles, aunque en Symbian [9] Pattern Recognition. Sergios Theodoridis y Konstantinos Koutroumbas. Academic Press, 1999. disponemos de todas las funciones que podamos necesitar, así como tipos double para cálculos decimales, etcétera, el programador debe evitar todo esto si quiere una aplicación eficiente. Lo correcto será implementar las funciones que necesite mediante otras técnicas como tablas de lookup, aritmética de punto fijo, etcétera, que también son aplicables en J2ME.

Por último, las aplicaciones que hagan uso del color y la luz de la imagen, como nuestro lector de colores, encontrarán su límite en el balance de blancos de la cámara, que no podemos controlar ni conocer su estado. En Symbian el problema sigue presente, aunque podemos escoger el perfil de iluminación más adecuado para la aplicación.

Por supuesto, la mayoría de estas limitaciones serán superadas por los nuevos terminales que están apareciendo al escribirse estas líneas, con mejores cámaras, no sólo en términos de resolución, sino también con zoom óptico, autoenfoque, flash, etcétera, y sobre todo , con mejores implementaciones de la

33 Actas del II congreso javaHispano

34 Actas del II congreso javaHispano

Programación de dispositivos Bluetooth a través de Java

Alberto Gimeno Brieba [email protected]

(OBject Exchange); se trata de un protocolo de alto nivel Abstract muy similar a HTTP.

En este documento se trata la programación de dispositivos Bluetooth con Java mediante el API desarrollada por el JCP 3 El paquete javax.bluetooth y especificada en el JSR-82. Primero abordaremos la programación de un cliente y Keywords: Java, Bluetooth, J2ME, JSR-82, móviles. más tarde veremos cómo programar un servidor.

3.1 Clientes Bluetooth 1 Introducción Un cliente Bluetooth deberá realizar las siguientes Bluetooth es una tecnología de comunicación operaciones para comunicarse con un servidor inalámbrica, al igual que la tecnología Wi-Fi o los Bluetooth: infrarrojos. A diferencia de la primera, Bluetooth está diseñada para dispositivos de bajo consumo y para • Búsqueda de dispositivos conexiones de corta distancia (10 metros). A diferencia • Búsqueda de servicios de los infrarrojos, Bluetooth es omnidireccional y tiene un mayor ancho de banda (hasta 11 Mbit/ segundo). • Establecimiento de la conexión

Bluetooth es, pues, una tecnología ideal para la conexión • Comunicación de dispositivos de bajas prestaciones (móviles, cámaras El punto de partida es la clase LocalDevice que de fotos, auriculares manos libres, impresoras,…). representa el dispositivo en el que se está ejecutando la Uno de los mayores ámbitos de utilización de Bluetooth aplicación. Este objeto es un singleton y se obtiene es sin duda los teléfonos móviles. Cada vez es más mediante LocalDevice.getLocalDevice(). Este objeto común encontrar terminales móviles con soporte para permite obtener información sobre el dispositivo: modo Java y Bluetooth y simplemente es un paso natural que de conectividad, dirección bluetooth y nombre del surja la necesidad de programar estos dispositivos a dispositivo. través de Java. Desde el JCP se ha desarrollado un JSR El primer paso que debe realizar un cliente es realizar que cubre esta necesidad. Se trata del JSR-82 que será una búsqueda de dispositivos. Para ello deberemos explicado en este documento. obtener un objeto DiscoveryAgent. Este objeto es único y se obtiene a través del objeto LocalDevice. 2 El JSR-82 DiscoveryAgent da = El JSR-82[1] especifica un API de alto nivel para la LocalDevice.getLocalDevice().getDiscoveryAgent(); programación de dispositivos Bluetooth. Depende de la El objeto DiscoveryAgent nos va a permitir realizar y configuración CLDC de J2ME, y se divide en dos cancelar búsquedas de dispositivos y de servicios. Y paquetes: javax.bluetooth y javax.obex. El primer también nos servirá para obtener listas de dispositivos ya paquete provee la funcionalidad para la realización de conocidos. Esto se lleva a cabo llamando al método búsquedas de dispositivos, búsquedas de servicios y retrieveDevices(). A este método se le debe pasar un comunicación mediante flujos de datos (streams) o argumento de tipo entero que puede ser: arrays de bytes. Por otro lado el paquete javax.obex permite la comunicación mediante el protocolo OBEX

35 Actas del II congreso javaHispano

• DiscoveryAgent.PREKNOWN. Para obtener una • DiscoveryListener.INQUIRY_COMPLETED si la lista de dispositivos encontrados en búsquedas búsqueda concluyó con normalidad, anteriores. • DiscoveryListener.INQUIRY_TERMINATED si la • DiscoveryAgent.CACHED. Para obtener una lista búsqueda ha sido cancelada manualmente o de dispositivos “favoritos”. • DiscoveryListener.INQUIRY_ERROR si se produjo El método retrieveDevices() devuelve un array de objetos un error en el proceso de búsqueda. RemoteDevice. La clase RemoteDevice representa un Ya hemos conseguido dar el primer paso para realizar dispositivo remoto y tiene métodos similares a una conexión cliente. El siguiente paso es realizar una LocalDevice que, recordemos, representa al dispositivo búsqueda de servicios. Antes de seguir deberemos en el que se ejecuta la aplicación. Así pues, podemos comprender ciertos conceptos. obtener el nombre del dispositivo mediante getFriendlyName() y su dirección bluetooth mediante Una aplicación cliente es una aplicación que requiere un getBluetoothAddress(). servidor para que le ofrezca un servicio. Este servicio puede ser: un servicio de impresión, un servicio de Podríamos omitir la búsqueda de dispositivos y pasar videoconferencia, un servicio de transferencia de directamente a la búsqueda de servicios en caso de que archivos, etc. En una comunicación TCP-IP un cliente se deseásemos conectar con alguno de los dispositivos conecta directamente a un servidor del que conoce el pertenecientes a alguna de estas listas. Sin embargo lo servicio que ofrece, es decir, conocemos a priori la más común será intentar conectar con un dispositivo localización del servidor y el servicio que nos ofrecerá; encontrado en una búsqueda de dispositivos, debido a sin embargo un cliente Bluetooth no conoce de que obviamente lo tendremos a nuestro alcance. antemano qué dispositivos tiene a su alcance ni cuáles Una búsqueda de dispositivos se inicia llamando al de ellos pueden ofrecerle el servicio que necesita. De método startInquiry(). Este método requiere un modo que un cliente Bluetooth necesita primero buscar argumento de tipo DiscoveryListener. DiscoveryListener los dispositivos que tiene a su alcance y posteriormente es una interfaz que implementaremos a nuestra les preguntará si ofrecen el servicio en el que está conveniencia y que será usada para que el dispositivo interesado. Este último proceso se denomina búsqueda notifique eventos a la aplicación cada vez que se de servicios y es el siguiente paso que un cliente debe descubre un dispositivo, un servicio, o se finaliza una realizar. búsqueda. Estos son los cuatro métodos de la interfaz Cada servicio es identificado numéricamente. Es decir, a DiscoveryListener: cada servicio le asignamos un número y para referirnos • deviceDiscovered() a dicho servicio usaremos su número asociado. Este identificador se denomina UUID (Universal Unique • inquiryCompleted() IDentifier). Adicionalmente, cada servicio tiene ciertos • servicesDiscovered() atributos que lo describen. Por ejemplo un servicio de impresión podría describirse por diversos atributos • serviceSearchCompleted() como: tipo de papel (dinA4, US-letter,…), tipo de tinta Los dos primeros métodos son llamados en el proceso (color, blanco y negro), etc. Los atributos también están de búsqueda de dispositivos. Los otros dos son llamados identificados numéricamente, es decir, para referirnos a en procesos de búsqueda de servicios. un atributo usaremos su número asociado.

Cada vez que un dispositivo es encontrado se llama al Las búsquedas de dispositivos también se realizan método deviceDiscovered() pasando un argumento de mediante el objeto DiscoveryAgent. Concretamente tipo RemoteDevice. usaremos el método searchServices() al que le tendremos que pasar un objeto DiscoveryListener que Una vez que la búsqueda de dispositivos ha concluido se recibirá los eventos de la búsqueda, el dispositivo en el llama al método inquiryCompleted() pasando como que realizar la búsqueda (un objeto RemoteDevice que argumento un entero que indica el motivo de la normalmente obtendremos en la búsqueda de finalización. Este entero puede valer: dispositivos), los servicios en los que estamos interesados, y los atributos que queremos conocer sobre

36 Actas del II congreso javaHispano

dichos servicios (tipo de papel, tipo de tinta, etc). Por open() y le pasaremos una URL que contendrá los datos ejemplo un cliente que esté interesado en un servicio de necesarios para realizar la conexión. impresión, para imprimir un texto probablemente sólo le No necesitaremos construir la URL a mano ya que el interese conocer el tipo de papel, sin embargo si objeto ServiceRecord posee un método que nos ahorra queremos imprimir una imagen estaremos también esta tarea: getConnectionURL(). interesados en si soporta o no tinta de color. Llegados a este punto debemos saber que tenemos dos Si se encuentra algún servicio se nos notificará a través formas diferentes de comunicación: a través de flujos de del objeto DiscoveryListener mediante el método datos utilizando el protocolo SPP (Serial Port Profile) , o servicesDiscovered(). Se nos pasará un array de objetos bien a través de L2CAP enviando y recibiendo arrays de ServiceRecord que encapsulan los atributos de servicio bytes. La forma más sencilla es mediante SPP. que solicitamos al invocar la búsqueda. Los valores de estos atributos de servicio son objetos DataElement. Si el servidor utiliza SPP el método Connector.open() nos devolverá un objeto de tipo Un objeto DataElement encapsula los tipos de datos en javax.microedition.io.StreamConnection. A través de los que puede ser representado un atributo de servicio. este objeto podemos obtener un (Data)InputStream y un Estos pueden ser: números enteros de diferente longitud (Data)OutputStream. Por lo tanto ya tenemos un flujo con o sin signo, cadenas de texto, URLs, booleanos, o de lectura y un flujo de escritura por lo que estamso en colecciones de DataElements. condiciones de leer y escribir datos. Un ServiceRecord es, pues, como una tabla que En caso de que el servidor utilice L2CAP el método relaciona los identificadores de los atributos con sus Connector.open() nos devolverá un objeto del tipo valores (objetos DataElement). javax.bluetooth.L2CAPConnection. Con este objeto Cuando finalice la búsqueda de servicios se nos leeremos bytes con receive() y escribiremos bytes con notificará mediante una llamada al método send(). serviceSearchCompleted() de la interfaz DiscoveryListener. Se nos pasará un argumento de tipo 3.2 Servidores Bluetooth entero indicando el motivo de la finalización. Este entero puede valer: La creación de un servidor Bluetooth es más sencilla que la programación de un cliente ya que no necesitamos • SERVICE_SEARCH_COMPLETED: la búsqueda ha realizar ningún tipo de búsqueda. Concretamente los finalizado con normalidad. pasos que debe realizar un servidor Bluetooth son los • SERVICE_SEARCH_TERMINATED: la búsqueda siguientes: ha sido cancelada manualmente. • Crear una conexión servidora

• SERVICE_SEARCH_NO_RECORDS: no existe la • Especificar los atributos de servicio información solicitada. • Abrir las conexiones cliente • SERVICE_SEARCH_ERROR: finalizó por un error. Crear la conexión servidora es relativamente simple. • SERVICE_SEARCH_DEVICE_NOT_REACHABLE: el Sencillamente debemos llamar al método dispositivo no está a nuestro alcance. Connector.open() pasándole una URL con una sintaxis Estas constantes son miembros de la interfaz determinada. En caso de querer comunicarnos mediante DiscoveryListener. SPP la URL comenzará por “btspp://” y en caso de querer comunicarnos mediante L2CAP la URL comenzará por Si hemos encontrado algún servicio que nos interesa “btl2cap://”. A continuación deberemos indicar pasaremos al siguiente paso: abrir la conexión. “localhost/” como host. Esto determina que no Abrir una conexión Bluetooth se lleva a cabo de la queremos conectarnos a nadie, sino que queremos ser misma forma que se abre cualquier otro tipo de servidores. Seguidamente sólo nos queda concatenar a conexión en CLDC: a través de la clase la URL el identificador del servicio (UUID) que vamos a javax.microedition.Connector. Usaremos su método ofrecer.

37 Actas del II congreso javaHispano

A continuación llamaremos al método Connector.open() • DISCONNECT. Usado para finalizar la sesión. pasando la URL como argumento. Si la URL comienza Las cabeceras de un mensaje OBEX son encapsuladas por por “btspp://” nos devolverá un objeto del tipo un objeto HeaderSet. Existen cabeceras de uso común javax.microedition.StreamConnectionNotifier y en caso como COUNT, NAME, LENGTH,… Sin embargo podremos de que la URL comience por “btl2cap://” nos devolverá crear cabeceras personalizadas. un objeto javax.bluetooth.L2CAPConnectionNotifier. La clase Operation provee la funcionalidad para leer y El siguiente paso es especificar los atributos de servicio. enviar mensajes que no sólo tienen cabeceras sino que Por ejemplo si vamos a ofrecer un hipotético servicio de también tienen un cuerpo de mensaje. Esta clase permite impresión podríamos indicar qué tipo de papel y de tinta obtener un (Data)InputStream y un (Data)OutputStream ofrecemos. Los atributos de servicio se almacenan en un para leer o escribir el cuerpo del mensaje. objeto ServiceRecord. Cada conexión servidora tiene un ServiceRecord asociado que se obtiene a través del Ahora que conocemos las clases básicas pasemos a ver LocalDevice. cómo programar un cliente OBEX.

Establecer los atributos de servicio es sencillo, simplemente tenemos que crear objetos DataElement y 4.1 Un cliente OBEX añadirlos al ServiceRecord. La programación de un cliente OBEX es relativamente Una vez establecidos los atributos de servicio ya estamos simple. Debemos abrir la conexión, como siempre en en condiciones de escuchar y procesar las conexiones CLDC con el objeto Connector. Deberemos pasarle una cliente. Para ello usaremos el método acceptAndOpen(). URL que comience por “irdaobex://” y nos devolverá un En una conexión servidora SPP este método devuelve un objeto de tipo javax.obex.ClientSession. Lo primero que javax.microedition.StreamConnection, y en una conexión deberemos hacer será ejecutar el método connect() para servidora L2CAP devuelve un objeto del tipo iniciar la sesión. javax.bluetooth.L2CAPConnection. En este punto ya A partir de aquí ya podemos realizar peticiones al podemos leer y escribir datos del mismo modo que lo servidor a través de los métodos put(), delete(), get() y hace un cliente. setPath(). Todos los métodos requieren un objeto HeaderSet como parámetro. Los métodos put() y get() 4 El paquete javax.obex adicionalmente devuelven un objeto Operation que permite escribir o leer el cuerpo del mensaje El paquete javax.obex permite manejar el protocolo de respectivamente. alto nivel OBEX (OBject Exchange). Se trata de un protocolo muy similar a HTTP. Al igual que este último, Para cerrar la sesión llamaremos al método disconnect(). OBEX se basa en mensajes compuestos por cabeceras de mensaje y opcionalmente de un cuerpo de mensaje. 4.2 Un servidor OBEX Adicionalmente los mensajes de respuesta del servidor poseen un código de respuesta indicando éxito o error. Crear una conexión servidora OBEX es también muy simple. Lo primero de todo es crear un SessionNotifier Al igual que en HTTP, los mensajes de petición del cliente llamando al método Connector.open(). La URL debe al servidor en OBEX se clasifican por métodos. Estos son comenzar por “irdaobex://localhost”. Ahora simplemente los métodos que existen. escucharemos las conexiones cliente llamando al método • CONNECT. Inicia la sesión. acceptAndOpen(). Este método requiere un argumento de tipo ServerRequestHandler. El ServerRequestHandler • PUT. Envía un archivo al servidor. es un objeto que deberemos implementar nosotros. Se • GET. Solicita un archivo al servidor. implementa de forma muy similar a un servlet: por cada método del protocolo OBEX tiene un método asociado al • DELETE. Solicita la eliminación de un archivo. que se le pasan los datos de la petición. Así pues • SETPATH. El cliente desea cambiar el directorio tenemos los métodos onConnect(), onGet(), onPut(), actual dentro del sistema de archivos del onDelete() y onDisconnect(). Todos los métodos tienen servidor. como argumento un objeto HeaderSet que encapsula las cabeceras de los mensajes, exceptuando los métodos

38 Actas del II congreso javaHispano

onPut() y onGet() que requieren un cuerpo de mensaje y de carrera. Pero sobre todo a todos los miembros de por ello su argumento es de tipo Operation. javaHispano por hacer esto posible.

Adicionalmente todos los métodos a excepción de onDisconnect() deben devolver un entero que será el Referencias código de respuesta indicando el éxito o no de la [1] Especificación del JSR-82: Bluetooth desde Java. petición y su motivo. http://jcp.org/en/jsr/detail?id=82. [2] Alberto Gimeno Brieba. JSR-82: Bluetooth desde Java. 5 Implementaciones del JSR-82 http://www.javahispano.org/tutorials.item.action?id=49.

Existen dispositivos móviles que soportan Java y tienen Bluetooth, pero sin embargo no soportan el API JSR-82. Esto quiere decir que no tenemos posibilidad de acceder al dispositivo Bluetooth a través de Java. Por ello habrá que acudir a las especificaciones del fabricante para cerciorarnos de que las APIs están soportadas.

A pesar de que el JSR-82 se especificó pensando en la plataforma J2ME. No sólo existen implementaciones y emuladores para J2ME. Debido a que J2ME es una versión reducida de J2SE, es perfectamente factible crear una implementación que pueda ser usada desde J2SE. De hecho existen implementaciones y emuladores. La mayoría de estas implementaciones son libres y suelen soportar dispositivos Bluetooth conectados al puerto serie. Otras implementaciones son bindings para Java de las APIs Bluetooth que ofrece el sistema operativo.

Ciertos emuladores y entornos de desarrollo también implementan estas APIs simulando dispositivos Bluetooth, es decir, permiten realizar aplicaciones que usen las APIs JSR-82 sin necesidad de tener físicamente un dispositivo Bluetooth.

6 Documentación

La documentación sobre las APIs definidas en el JSR-82 es muy escasa y mucho más escasa es en español. Sin embargo en javaHispano se publicó un tutorial[2] al respecto en el que se puede encontrar mas información y enlaces a otros documentos.

Por último añadir que siempre es fundamental tener a mano la documentación javadoc de las APIs, la cual se puede descargar desde la página del JSR-82[1] junto con la especificación.

Agradecimientos

Agradezco su apoyo a la Escuela Universitaira Politécnica de La Almunia, a Ángel Blesa y a todos mis compañeros

39 Actas del II congreso javaHispano

40 Actas del II congreso javaHispano

Mem oria dinám ica en JavaCard: una herram ienta para superar las lim itaciones

Borja Bravo Alférez David Fraga Aydillo [email protected] .es [email protected] .es

proteger la inform ación que contienen. Abstract Norm alm ente guardan datos im portante com o el núm ero de cuenta bancaria o las claves de La plataform a JavaCard es una tecnología basada en las autenticación en una red GSM. tarjetas inteligentes que, teniendo im portantes ventajas, actualm ente no siem pre perm ite recuperar la m em oria Para controlar el acceso a los datos éstas tarjetas reservada. Esto tiene im portantes inconvenientes para el incluyen un pequeño procesador. Esta CPU en program ador y lim ita la inteligencia de la tarjeta. Nosotros ocasiones está acom pañada de coprocesadores presentam os una herram ienta que pretende elim inar esta criptográficos para realizar algoritm os de seguridad im portante restricción. La solución consiste en crear un sofisticados. Todo esto hace de las tarjetas applet que reserve la cantidad de m em oria deseada y la inteligentes la plataform a ideal para prestar servicios ofrezca com o servicio al resto de las applets de la tarjeta. que requieren un nivel de seguridad im portante. Este servicio tiene que realizarse de form a segura para que Por ejem plo: banca y m onedero electrónico, un applet presum iblem ente hostile, puedan obtener o identificación, control de accesos, alm acenam iento alterar inform ación de otra applet. de claves y servicios de transporte. Pero quizás el ejem plo m ás conocido es la om nipresente tarjeta Una vez diseñado el servicio de creación de m em oria, se SIM del los teléfonos GSM. Adem ás, existen tiene un dispositivo de alm acenam iento capaz de guardar m odalidades inalám bricas que, con prácticam ente la m em oria de form a sencilla. Cóm o la m ayoría de m ism a seguridad, funcionan con sólo acercarse a aplicaciones no necesitan m ás, se propone una capa de un lector lo que nos ahorra tener que sacarlas del com unicaciones que perm ita a un usuarios externo a la bolsillo. tarjeta solicitar acceso a la m em oria reservada, así com o pedir su propia m em oria. Con este sistem a el esfuerzo del Las tarjetas carecen de periféricos que la desarrollador de soluciones se centrará en el term inal y la com uniquen con el exterior salvo la conexión serie, red. Com o ejem plo, se pretende que un PC equipado con ya sea por el clásico conector eléctrico, el un lector de tarjetas pueda acceder al servicio de m em oria inalám brico o am bos en el caso de las tarjetas y m ontar el dispositivo com o un sistem a de ficheros híbridas. Toda la com unicación con el exterior GNU/Linux. consiste en un intercam bio de m ensajes llam ados APDUs (Application Protocol Data Unit). Mediante el Keywords: JavaCard, Mem oria, Liberación de Mem oria, Sm art Cards, tarjetas inteligentes, Linux

1 Introducción a las tarjetas inteligentes.

Las tarjetas inteligentes son dispositivos de alm acenam iento con form a de tarjeta de crédito que em plean algoritm os criptográficos para acceder y

41 Actas del II congreso javaHispano

envío y recepción de APDUs según los estándares la inteligencia en la tarjeta y no en el term inal o en la ISO se puede acceder a la inform ación de la tarjeta. red a la que éste se conecte: Por supuesto, esto im plica conocer una serie de - Para ahorrarse una red de claves internas. Adem ás, la tarjeta está diseñada telecom unicaciones entre todos los para resistir físicam ente los intentos de acceder a term inales. Ej: El acceso a los arrastres en los datos que contiene. una estación de esquí.

- Para ahorrar ancho de banda. Ej: Una aplicación podría estar com o un servicio 2 Necesidad de la tecnología JavaCard. wap o en la tarjeta, pero en la tarjeta no produce trafico que sature la red GSM. Una tarjeta inteligente puede ser suficiente en m uchos casos para m ontar un servicio sobre ella. Sin - Porque necesitam os desplegar una em bargo, hay dos hechos fundam entales que aplicación en un entorno donde no justifican la introducción de una m áquina virtual controlam os todos los term inales. Ej: Una JavaCard en las tarjetas inteligentes: aplicación que funcione incluso en los cajeros autom áticos de la com petencia o en Prim ero: la proliferación de tarjetas inteligentes y todos los m odelos de teléfono m óvil. m agnéticas obliga al usuario a poseen dem asiadas de ellas en la cartera. Esto no es m uy practico - Para realizar controles de seguridad m ás allá teniendo en cuenta que no son tan baratas com o de los perm itidos por los estándares de ISO. podría parecer y, ahora m ism o, las tarjetas tienen Ej: cualquier nuevo protocolo de capacidad suficiente com o para contener la autenticación y encriptación. inform ación de varios servicios. Pero para que yo - Y porque en general es necesario hacer pueda tener todas m is aplicaciones en una sola ciertas cosas en el cliente. Ej: Podem os tarjeta necesito: restringir los m ensajes a ciertos núm eros A) Un m étodo de acceso para grabar y elim inar m ediante la tarjeta, pero si lo hacem os en el inform ación de cada aplicación en una m óvil el usuario siem pre puede cam biar de tarjeta. term inal.

B) Un esquem a de protección entre la Una vez convencidos de que querem os colocar una inform ación de diversos proveedores de aplicación que se ejecute dentro del chip de la servicios. tarjeta inteligente necesitam os inform ación sobre instrucciones, registros, m em oria y el resto de datos C) Un sistem a por el cual el usuario o el em isor para program ar en un PC. de la tarjeta pueda dar acceso a diferentes proveedores de servicios. Los fabricantes han desarrollado diversos sistem as operativos y hardware sobre le que ejecutarlos. El Segundo: Una tarjeta puede ser una sim ple m em oria resultado es que una aplicación program ada para pero, recordem os que por cuestiones prácticas se una tarjeta, raram ente funcionará en otra. JavaCard im plem enta el control de acceso m ediante un es una solución elegante a am bos problem as. Por un procesador, y sabiendo que tenem os una m em oria lado perm ite cargar y borrar pequeñas aplicaciones EEPROM, tenem os un m icrocontrolador capaz de leer llam adas applets en la tarjeta. Dichas applets los datos y ejecutar program as. Esto llevó a la idea contienen su propia inform ación independiente y de de que la tarjeta podría realizar servicios m ucho m ás form a protegida. El diseño de Java es m uy adecuado elaborados y com plejos que sim plem ente alm acenar puesto que no tiene punteros, pero hay otras inform ación. m edidas de seguridad com o un firewall entre applets Hay quien puede poner en duda la necesidad de y borrado de cierta inform ación cuando se resetea la estas aplicaciones pero existen algunas razones por tarjeta. las que en ocasiones es interesante colocar parte de En cuanto a la ejecución de aplicaciones, el entorno Java lleva años solucionado en el m undo de los PCs

42 Actas del II congreso javaHispano

el m ism o problem a que ha surgido en las tarjetas: Java Card technology does not require a garbage las diferencias de hardware y software bajo las que collector. Nor does Java Card technology allow se ejecuta un program a. En otras palabras, garantiza explicit deallocation of objects, since this would una cierta interoperabilidad. break the Java program m ing language’s required pointer-safety. Therefore, application program m ers Adicionalm ente ganam os una ventaja nada cannot assum e that objects that are allocated are despreciable. Y es que hay una base im portantísim a ever deallocated. Storage for unreachable objects de program adores con experiencia en el lenguaje will not necessarily be reclaim ed. Java m ientras que es m uy difícil encontrar personas con experiencia en los diferentes sistem as Finalization is also not required. finalize() will not operativos de las tarjetas. necessarily be called autom atically by the Java Card virtual m achine, and program m ers should not rely on this behavior [1] 3 Algunas dificultades de la tecnología Por si no ha quedado suficientem ente claro, no sólo JavaCard: el problem a de la m em oria. no hay un recolector de basura, sino que no hay Aunque hem os visto que un desarrollo basado en la ninguna m anera posible de recuperar la m em oria tecnología JavaCard tiene m uchas ventajas hay perdida. Hasta tal punto es eso que en la guía del algunos problem as entre los que destacam os: desarrollador de applets se recom ienda no em plear el m étodo new m ás que en m étodo de instalación[2]. - El entorno de trabajo está m uy restringido por la m em oria, capacidad de proceso y Para entender el problem a debem os conocer un velocidad de entrada salida. Por lo tanto la poco m ás com o funciona el cam bio de contexto tarjeta no soportará cualquier aplicación. entre aplicaciones. Un applet puede estar seleccionada o no seleccionada. Cuando un lector - A pesar de que el entorno JavaCard es desea hacer funcionar un applet en concreto la m ucho m ás ligero que el de otros entornos selecciona. Esto es conveniente porque cada applet Java, la m áquina virtual y el resto de la tiene que saber que APDUs son para ella y cuales no. plataform a ocupan unos recursos m uy Recientem ente JavaCard soporta hasta 4 canales valiosos de la tarjeta. lógicos, una form a de m ultiplexar APDUS entre - Y por últim o, pero para nosotros lo m ás applets, pero sólo en las últim as versiones. Así pues, im portante, Las im plem entaciones actuales podríam os asum ir que durante el procesado se use de JavaCard carecen de m ecanism os para m ucha m em oria y que en le cam bio de contexto se recuperar la m em oria reservada. grabe lo m ínim o o se libere la m em oria RAM. Adem ás, existen consideraciones prácticas. Este últim o problem a puede resultar sorprendente a Supongam os tres aplicaciones: una gestiona una m ás de un lector. ¿Por qué im pedirlo? Posiblem ente cerradura electrónica de la puerta de casa, otra es los diseñadores de JavaCard consideraron el peligro un m onedero electrónico y la últim a es un sistem a de quedarse sin m em oria y tom aron las m edidas de fidelización por puntos de m i hiperm ercado. para que esto no ocurriera. O quizás no encontraron ¿Cuál es la probabilidad de usar las tres aplicaciones una alternativa ligera al recolector de basura. En a la vez? Prácticam ente ninguna. Incluso podríam os cualquier caso es un diseño en el caso peor. Muy entender que el superm ercado te conceda los seguro pero no lo m ás eficiente para un entorno que puntos después de pagar con m onedero electrónico, hoy en día no superan los 64KB de m em oria. pero, eso no significa que tengan que ejecutarse am bas applets a la vez en vez de una detrás de otra. 4 Descripción del problem a a resolver Por lo tanto el riesgo de que nos quedem os sin m em oria por usar todas las applets a la vez Si leem os la docum entación de la plataform a podem os considerarlo bastante pequeño. JavaCard 2.1.1 encontram os: Sun ha reaccionado para superar el problem a. En la Garbage Collection & Finalization edición 2.2.1, se perm ite la inclusión de un recolector de basura. Pero queda com o una

43 Actas del II congreso javaHispano

característica opcional, es decir, las applets que - Las im plem entaciones recursivas deben em pleen recolector de basura no funcionarán en evitarse puesto que consum en una cantidad aquellas tarjetas que no lo tengan im plem entado. de m em oria no acotada. De hecho cualquier m étodo que construya variables de form a ¿Arreglado no? Me tem o que no. Actualm ente Sun dinám ica no es una buena idea puesto que calcula que hay 750 m illones de tarjetas JavaCard obliga a ir perdiendo m em oria poco a poco. vendidas en el m undo. Adem ás, todavía es extrem adam ente difícil encontrar fabricantes de - Es m uy posible que el program ador se vea tarjetas con una im plem entación de la m áquina obligado a reutilizar variables. Por ejem plo virtual 2.2.1 de Java. Y recordem os que la inclusión puede declarar un array genérico y usarlo al del recolector de basura sigue siendo voluntaria. principio com o buffer de entrada y luego para otras cosas. No es elegante, com o En cualquier caso, la sustitución de todas las tarjetas práctica de program ación es bastante m ala, a los usuarios puede resultar m uy cara. Tanto por la pero al program ador le piden que no propia tarjeta com o por el proceso y la m ano de consum a m ucha m em oria. obra. Adem ás, m uchas de estas tarjetas poseen inform ación im portante que guardar. Por ejem plo, el - Hay que definir m uy bien el espacio m áxim o saldo de un m onedero electrónico o la agenda las que va a utilizar cada objeto. Los objetos de tarjetas SIMs. Eso significa que no basta con enviar a tam año variable que se construyen sobre la casa una carta con una tarjeta nueva, sino que m archa no deben existir salvo que sólo se alguien tiene que desplazarse físicam ente a un lugar construyan una única vez. Y, en ese caso, no especializado donde realicen un duplicado de l podrán cam biar de tam año. tarjeta en un m odelo superior. - Si quieres pasar 8 argum entos a una función En cierto m odo la instalación de las applets tam bién no puedes construir un objeto con esos 8 puede serlo. Sin em bargo algunas de esas tarjetas argum entos y pasarlo puesto que nunca incorporan la tecnología OTA1 (Over The Air) que lo recuperarías la m em oria del objeto. En el hace trem endam ente sencillo. OTA es un m étodo peor de los casos puedes construir un para instalar applets m andando APDUS sobre la red objeto estático y usarlo cada vez que se m óvil, ya sea GSM, GPRS o UMTS. llam e a la función.

Hem os visto el punto de vista económ ico, pero Resum iendo, la im posibilidad de recuperar la ¿Hasta qué punto representa un problem a para el m em oria dinám ica lim ita la inteligencia que puede program ador la im posibilidad de borrar objetos? contener la tarjeta y hace la vida m ucho m ás difícil a Veam os algunos casos: los program adores puesto que tienen que cam biar su estilo de program ación. - Com o las applets crean sus objetos al instalarse y nunca los borran la cantidad de Adem ás, debem os tener en cuenta que la tarjeta applets instaladas o su com plejidad se posee tres tipos de m em oria. ROM, EEPROM y RAM. reduce de una form a drástica. Es com o si La RAM es m uy escasa pero m uy im portante. Sin ella obligases a tu ordenador a que tuviese cualquier algoritm o que requiera alm acenar abiertas todas las aplicaciones a la vez, solo resultados parciales será terriblem ente lento. Una que en este caso el ordenador de gam m a aplicación típica puede necesitar que el procesado alta tiene 64 KB. Desde otro punto de vista sea en RAM para realizarse en un tiem po razonable, podem os decir que es necesario com prar pero, una vez term inadas sus operaciones puede tarjetas con bastante m ás m em oria y por lo guardar el resultado en EEPROM y liberar la valiosa tanto m ás caras para una serie de RAM para otras aplicaciones. Tal com o vim os, lo aplicaciones dada. norm al es que sólo haya un applet seleccionada y, teniendo en cuenta que sólo hay 4KB de RAM posiblem ente es lo m ás conveniente.

1 En realidad OTA no se lim ita a la tarjeta sino que puede servir para actualizar el firm ware de un term inal o descargar un juego.

44 Actas del II congreso javaHispano

4 Solución que planteam os.

Vam os a aprovechar los m ecanism os que perm iten com partir m em oria para plantear una posible solución al problem a de la m em oria dinám ica. Un applet puede reservar una cantidad de m em oria im portante y ofrecerla al resto de las applets com o si de un servicio del sistem a se tratara. Lo único que com probar que la identidad es correcta es solicitar hay que decidir es qué cantidad de m em oria una referencia a ese objeto. querem os reservar y esto podem os decidirlo en la instalación. Luego cada applet podrá solicitar y Sin em bargo el asunto m ás com plejo ha sido com o devolverla cuando quiera. Es posible que para organizar la m em oria. Norm alm ente este problem a algunas aplicaciones esto represente una está m uy estudiado por los diseñadores de sistem as sobrecarga, pero, pero queda a la elección del operativos. En nuestro caso tenem os una lim itación program ador cuando le resulta im portante poder im portante, la m em oria EEPROM es trem endam ente recuperar la m em oria y cuando prefiere un poco m ás lenta de escribir. Por esa razón necesitábam os de velocidad. En cualquier caso, es im portante tener m inim izar todo aquello que requiera cam biar de en cuenta que el servicio de reserva de m em oria sitio la m em oria reescribiendo la inform ación de un tiene que ser seguro para que una aplicación hostil lugar a otro de la m em oria disponible. no se haga con inform ación im portante. Tradicionalm ente se em plean tres soluciones clásicas: paginación, segm entación y segm entación paginada. El problem a de la segm entación es que 5 Notas de diseño produce fragm entación externa que te obliga a El applet que sirve de m ódulo servidor de m em oria cam biar de sitio un segm ento, que es justo lo que crea un gran array de Bytes y una serie de m étodos deseam os evitar. Entre la paginación y la de acceso. Pero, en ningún caso se puede devolver segm entación paginada la decisión no está tan clara. una referencia a este array puesto que, el applet La paginación es m enos eficiente en m em oria pero podría acceder a la m em oria de otras applets. requiere m enos procesado. El problem a es que la Tam poco podem os crear y pasar un array a m edida segm entación paginada suele im plem entarse en un porque, nunca podríam os recuperar la m em oria de sistem a con hardware adicional del que carecem os. ese array. Por lo tanto, tendrem os que pedir la Al intentar realizarlo por software la com plicación se inform ación de tipo básico en tipo básico. dispara y resulta poco m anejable. Así pues, después de algunas pruebas con segm entación paginada, nos La autenticación usa un sistem a m uy curioso. decidim os por la paginación com o m étodo de Norm alm ente las Applets que quieren com partir organización de la m em oria. recursos usan su identificador de Applet (el AID) y a lo sum o pueden pasar algún argum ento y pedir un Los fragm entos de m em oria están descritos desafío para garantizar la identidad. En realidad no m ediante una serie de inodos que se alm acenan en es m uy seguro puesto que un applet puede la m ism a m em oria. Aquellas zonas de m em oria que registrarse con un AID falso. Esto es un problem a requieran m ás de una página tienen inodos porque cualquiera que consiga una clave puede secundarios que están unidos m ediante una lista hacer m ucho daño. Por otro lado no podem os doblem ente encadenada. En cierto m odo cada uno perm itirnos que cada vez que leam os un byte haya de esos fragm entos de m em oria puede considerarse que hacer unas operaciones com plicadas de un archivo. Adem ás, en los inodos se aprovecha criptografía. La solución que hem os adoptado es para incluir inform ación sobre: m uy diferente. Cada applet, antes de pedir m em oria - Perm isos de lectura y escritura debe registrarse enviando una referencia a un pequeño objeto al que llam arem os llave. Cóm o el - Un sistem a de grupos entorno JavaCard im pide que otra applet consiga - Un rudim entario sistem a de directorios una referencia a ese objeto la form a m ás sencilla de

45 Actas del II congreso javaHispano

El sistem a de perm isos es m uy sencillo y consiste en 6. Operaciones especificas del sistem a y 6 bits RW al estilo Unix. instrucciones de depuración.

El sistem a de grupos perm ite que cada archivo en Obtienen la m em oria libre y la ocupada así com o m em oria tenga un dueño y un grupo. Crear un ayudan a la depuración sistem a de grupos en un sistem a de acceso com partido a la m em oria. Otra form a sería tener 7 Ejem plo de funcionam iento varias llaves diferentes y com partir las llaves con acceso a inform ación que se desee ofrecer y Inicialm ente el m odulo de m em oria crea una interfaz m antener privadas las que no. shareable con la API que ofrece al exterior. Un applet cualquiera puede pedir una copia de ese interfaz. El sistem a de directorios, básicam ente consiste en el Para ello debe conocer cual es el identificador (AID) tradicional árbol de referencias entre archivos y está del m ódulo de m em oria. pensado para quien quiera usar la tarjeta com o un sistem a de alm acenam iento m ás. Una vez con una copia de la Interfaz, el applet cliente puede llam ar a los m étodos sobre los que dicha interfaz proporciona acceso. Al principio, el 6 API del m ódulo de m em oria applet cliente no tiene apenas perm isos. Sólo puede Podem os clasificar las instrucciones en varios crear su propia llave, registrarla, y a partir de grupos: entonces solicitar y m anejar su propia m em oria. Si necesita leer la m em oria de otra applet será ésta 1. Instrucciones de creación y elim inación de quien se los deba conceder. Esto lo pueden hacer usuarios. creando grupos y asignando los perm isos Función register y unregister para las claves de las correspondientes. De esta form a dos applets pueden applets y adduser y del user para los usuarios com unicarse y actuar de form a coordinada. externos del m ódulo de m em oria.

2. Instrucciones de reserva de m em oria. 8 Com unicación con el exterior

Las equivalentes al m alloc, free, y realloc. Adem ás, Una vez que tenem os un applet capaz de ofrecer una devuelve la longitud del fragm ento de m em oria, m em oria puede ser m uy interesante com partirla con y free tiene dos m odalidades: una borra la m em oria el exterior. En caso contrario será la propia applet la y otra no. Esto es así porque recordem os que la que tenga que interceptar APDUS que le lleguen, EEPROM es m uy lenta de escribir. Pero en ocasiones, construir sus propias APDUs de respuesta con la por seguridad, es intolerable no borrar. inform ación oportuna. Esto supone m ás trabajo de 3. Instrucciones de lectura y escritura. program ación. Algunas aplicaciones querrán encargarse ellas m ism as de gestionar las APDUS de Instrucciones de leer y escribir byte y short. Tam bién salida, pero existe una inm ensa cantidad de uno que copia un arrary com pleto para ahorrar aplicaciones en las que no necesitam os capacidad de sobrecarga en arrays grandes. proceso en la tarjeta. Podríam os usar este m ódulo 4. Operaciones de cam bio de perm isos y grupos. de m em oria para perm itir la escritura en la tarjeta con las condiciones que describíam os en la prim era Chown, Chm od, crear y elim inar grupos m ás unas un parte del punto dos. Tenem os una tarjeta que poco específicas del sistem a. perm ite escribir y leer datos de form a segura y 5. Operaciones en el sistem a de directorios obtener el inodo del directorio padre, obtener perm isos, obtener el núm ero de archivos en el directorio, obtener un hijo. Adem ás, tenem os m v, cp, m kdir y las operaciones del nom bre de directorio que ecriben, recuperan y borran el nom bre de un fichero

46 Actas del II congreso javaHispano

m ultiusuario con la ventaja de no tener que querem os que al cam biar de m óvil nos sigan program ar la parte de com unicaciones. sirviendo los m ism os datos.

Para lograr que esto funcione alguien tiene que En esta caso querem os varias cosas: haber program ado un m ódulo de com unicaciones A) Poder introducir fechas de cum pleaños en el que se encargue de traducir las llam adas y respuesta m ediante el teléfono m óvil. a la API en APDUs. Ese m ism o applet recurre al m odulo de m em oria igual que cualquier otro applet. B) Poder gestionar en casa las fechas m ediante La única diferencia es que internam ente alm acena el ordenador, que es m ás cóm odo y rápido una serie de llaves para funcionar com o uno u otro gracias al teclado usuarios. Debe im plem entarse un m ecanism o de C) Que suene una alarm a 24 horas antes de autenticación para que el m ódulo de cada cum pleaños. com unicaciones reconozca al usuario y use la llave alm acenada de ese usuario. Pero, por suerte, si hay Para el interfaz del teléfono m óvil podem os utilizar algo que las tarjetas JavaCard saben hacer es una tarjeta y m óvil USAT4 (Universal Sim Application autenticar usuarios con seguridad. Toolkit). Esto perm ite colocar un nuevo m enú una parte del m óvil en el que podem os poner un m enú Una vez especificado el protocolo de llam ado “agenda cum pleaños” con las opciones com unicaciones m ediante APDUs, si cargam os una “añadir”, “editar” y “elim inar” que se com portarán de tarjeta con las applets del m ódulo de m em oria y la m anera esperada. Por supuesto, la inform ación se com unicaciones, cualquiera puede intentar usar la alm acenaría, en un form ato que nos resulta tarjeta com o un dispositivo de alm acenam iento. indiferente, dentro del m ódulo de m em oria. Pero al Adem ás, puede hacerlo sin lim itaciones a la hora de instalar nuestra applet usarem os los perm isos liberar objetos y no necesita perm isos especiales especiales del súper usuario para crear un usuario para cargar un applet. El usuario solo necesita externo que esté en el m ism o grupo que el applet m andar las APDUs apropiadas para registrarse, agenda de cum pleaños. Por lo tanto una aplicación reservar y acceder a la m em oria. externa podría leer y escribir el archivo de datos de ¿Y qué puedo hacer con esto? Muchas cosas. Entre la tarjeta m ediante APDUs, editarlo en el PC y otras cosas, estam os estudiando realizar un sistem a finalm ente actualizar los cam bios en la tarjeta. de ficheros para m áquina GNU / Linux que use el Incluso, podría perm itirse que el usuario se contenido del m ódulo de m em oria com o dispositivo descargue el archivo y lo edite a m ano. m ás. Claro que, para eso, necesito un lector de Finalm ente, podem os hacer uso de los tonos y la tarjetas. Un problem a frecuente es que las pantalla del m óvil m ediante el USAT para hacer aplicaciones estén diseñadas para un lector en sonar las alarm as y m ensajes que nos avisen de que concreto. Por eso es recom endable incluir en el tenem os que ir pensado un regalo de cum pleaños. cliente una capa de abstracción que en nuestro caso será el protocolo PCSC Lite2, una versión reducida del estándar3 PCSC de Microsoft. 10 Perspectivas futuras

En prim er lugar, parece que la lim itación de la 9 Ejem plo de aplicación cantidad de m em oria es, afortunadam ente cada vez m enor. Varios fabricantes afirm an que Supongam os que querem os hacer una aplicación com ercializarán tarjetas de al m enos un MByte. Esto que sirva de agenda de cum pleaños en la tarjeta SIM es un salto de dos órdenes de m agnitud. Parece ser del m óvil. Muchos m óviles ya lo im plem entan pero que sustituyendo la m em oria EEPROM por flash se quizás nuestro term inal no lo haga o sim plem ente podría llegar hasta los cientos de m egas en un futuro cercano.

2 Para m ás inform ación sobre PCSC Lite consultar http://pcsclite.alioth.debian.org/

3 La especificación de PCSC está dispoible en 4 A veces es posible encontrar una referencia a USAT com o STK o http://www.pcscworkgroup.com / sencillam ente SIM Toolkit

47 Actas del II congreso javaHispano

Por otro lado, puede que las nuevas tarjetas incorporen la nueva m áquina virtual JavaCard, y, si éstas incluyen recolector de basura, se elim inaría el problem a de la liberación de la m em oria. Adem ás, las nuevas tarjetas para m óviles de tercera generación parece ser que incorporarán JavaCard en una proporción m uy im portante. Tam bién incorporarán el Sim Toolkit (USAT) por defecto. Adicionalm ente. Varios estándares5 sobre JavaCard en la tarjeta SIM por parte del 3GPP ( 3rd Generation Partnership Project ). Eso significa que en un futuro próximo es posible que prácticamente todas las tarjetas de móviles UMTS se entreguen con una máquina virtual JavaCard.

Por nuestra parte, tenem os planteado desarrollar el sistem a de ficheros en GNU / Linux m ediante un m ódulo de FUSE6 y a través de la biblioteca PCSClite.

Finalm ente, es posible que en cuestión de un año o m eses las operadoras com iencen a distribuir aplicaciones con la m ism a facilidad con que se envían tonos al m óvil.

Agradecim ientos

A todos aquellos que hacen del laboratorio lo que es. Especialm ente a David y Rover por ser incansables a la hora de resolver dudas. Y a todos por todas esas horas de futbolín. Algún día os ganaré a todos.

Referencias:

[1] Java Card 2.1 Virtual Machine Specification. 2.2.1.1 pag 8 [2] Java Card Applet Developer’s Guide. Rev 1-10 Capítulo 4, página 2.

5 Por ejem plo el 3GPP TR 31.919: 2G/3G Java Card™ API based applet interworking.

6 FUSE significa Filesystem in User Space y com o su propio nom bre indica es un m étodo para im plem entar un sistem a de ficheros linux sin tener que m odificar el nucleo. Más inform ación en: http://fuse.sourceforge.net/

48 Actas del II congreso javaHispano

JVMTI, creación avanzada de profilers de aplicaciones con la nueva API de Tiger

Daniel Glez-Peña Florentino Fdez-Riverola [email protected] [email protected]

el objetivo de encontrar posibles cuellos de botella Abstract durante su ejecución. Las funcionalidades que proporcionan son más variadas, aunque suelen ser JVMTI (Java Virtual Machine Tool Interface), es la nueva API típicas las de análisis de memoria (clases cargadas, de J2SE 5.0 orientada principalmente al desarrollo de número de instancias, bytes ocupados) y análisis de CPU agentes de depuración y profiling. (métodos invocados, su duración y su orden dentro de La implementación de profilers en las versiones anteriores a cada thread). Ejemplos de profilers comerciales son J2SE 5.0, se realizaba mediante JVMPI (Java Virtual Machine Borland OptimizeIt Profiler, ej-Technologies JProfiler, etc; Profiler Interface), todavía en fase experimental. La existiendo además soluciones libres como hprof (incluido migración de proyectos realizados con la API antigua a la en el J2SDK), Eclipse Profiler Plugin, jprof, JavaTraceIt!, nueva, no es trivial en la mayor parte de los casos. Una etc. diferencia importante es que JVMTI requiere casi siempre del uso de BCI (Byte-code Instrumentation), es decir, la modificación del byte-code de las clases cargadas para la generación de callbacks hacia el agente. 1.1 JVMPI y JVMDI

JavaTraceIt! es una herramienta de código libre orientada a Si JVMTI es una interfaz nueva y los profilers y la depuración y optimización de código Java. Su profiler depuradores son herramientas ya tradicionales en Java, había sido realizado utilizando JVMPI, por lo que ha sido la respuesta a la pregunta de cómo se desarrollaban necesaria su migración a JVMTI debido al fin anunciado de hasta ahora la encontramos en JVMPI y JVMDI, dos APIs la antigua API. actualmente sustituidas por JVMTI. JVMDI (Java Virtual Machine Debug Interface) fue Keywords: Java Virtual Machine Tool Interface, Java introducida en el J2SDK 1.1 y estaba destinada al Virtual Machine Profiler Interface, Java Virtual Machine desarrollo de depuradores. Formaba parte de JPDA (Java Debug Interface, JavaTraceIt!. Platform Debugger Architecture), que sigue existiendo en J2SE 5.0, pero con la sustitución de JVMDI por JVMTI. La Figura 1 muestra de manera esquemática este hecho. 1 Introducción JVMTI es una nueva interfaz nativa disponible en J2SE 5.0, que se utiliza en herramientas de desarrollo de software y de monitorización. Proporciona un modo común tanto para controlar la ejecución como para inspeccionar el estado de las aplicaciones que se ejecutan en la JVM (Java Virtual Machine). En este sentido, los dos grandes grupos de herramientas que utilizarán JVMTI son los depuradores (control de la ejecución) y los profilers (inspección del estado). Los depuradores suelen ser parte fundamental de un IDE (Integrated Development Enviroment), siendo de gran Figura 1: JPDA antes y después de J2SE 5.0. ayuda para la detección de errores en el código. Las funciones clásicas de un depurador son la traza o Como se puede observar en la Figura 1, la capa superior ejecución paso a paso de código, el establecimiento de de JPDA es JDI (Java Debug Interface), una API 100% puntos de ruptura o breakpoints y el seguimiento de los Java de alto nivel con la que Sun recomienda que se valores de las variables. Los IDE para Java dotados de un desarrollen los depuradores. De este modo, los depurador han existido desde los comienzos de la depuradores ya desarrollados con esta API, no se verán plataforma, siendo hoy en día difícil hacer un recuento en absoluto afectados por la desaparición de JVMDI. de todos ellos. Ejemplos de depuradores son, por un JVMPI (Java Virtual Machine Profiler Interface) fue lado, soluciones comerciales como VisualCafé, JBuilder y introducida también en el J2SDK 1.1, pero siempre ha Sun Java Studio, y por otro, soluciones libres como sido tratada con carácter experimental. Esta API fue NetBeans, Eclipse, BlueJ, JavaTraceIt!, etc. migrada a la HotSpot JVM, en el J2SDK 1.3, pero nunca Por otro lado, un profiler se puede definir como una llegó a ser tan estable como en la JVM clásica. JVMPI utilidad que analiza el rendimiento de un programa con presentaba múltiples inconvenientes: hacía uso de object

49 Actas del II congreso javaHispano

IDs en vez de objetos JNI, lo que añadía dificultad; los formatos de volcado del montón eran complejos; ciertos recolectores de basura no funcionaban. Además, el uso de JVMPI tenía un impacto importante en el rendimiento de la JVM. Esta API ha pasado a estar obsoleta (deprecated) en el J2SE 1.5.0 (o 5.0), con vistas a ser eliminada en la próxima versión 1.6.0. El problema se plantea en los profilers ya existentes, que usan obligatoriamente JVMPI, puesto que nunca ha existido una arquitectura mayor que pudiese abstraer a los desarrolladores de usar esta API, al contrario de lo que ocurre con JVMDI en los depuradores (ver Figura 1). La dificultad de la migración a la que están obligados los desarrolladores de profilers, dependerá del uso que se hacía de la API JVMPI, pero en la mayor parte de los casos no es un proceso sencillo, debido a los grandes cambios que se presentan en JVMTI. A continuación se presentan los conceptos básicos de JVMTI (sección 2), los pasos básicos para la construcción de un agente JVMTI (sección 3) y una breve introducción a BCI (sección 4). Finalmente se comentan los detalles Figura 2: Arquitectura general de un sistema con JVMTI. más destacables de la migración realizada en Los eventos JVMTI a los que se puede atender son muy JavaTraceIt! para la adopción de JVMTI (sección 5) y se numerosos. Dependiendo de la finalidad del agente se apuntan las conclusiones más relevantes. atenderán unos u otros. Para ello existen funciones que permiten especificar:

2 Conceptos básicos de JVMTI • Qué eventos se desean tratar. Por ejemplo, no son muy necesarios eventos orientados a un JVMTI puede ser vista como una interfaz de dos vías. Un agente de depuración cuando se está realizando cliente de JVMTI, llamado agente es notificado de un agente de profiling, como pueden ser los sucesos de interés a través de eventos. Por otro lado, eventos relacionados con los puntos de ruptura JVMTI puede controlar y consultar la aplicación a través o breakpoints. de funciones, utilizadas en respuesta a los eventos, o de modo independiente a ellos. • Qué funcion se llamará cuando llega el evento. Es necesario establecer un puntero a una Los agentes corren en el mismo proceso y se comunican función que hará de callback para el evento. directamente con la Máquina Virtual que ejecuta la aplicación monitorizada. Esta comunicación es la que se Es preciso destacar que JVMTI no controla los eventos hace a través de JVMTI a través de los eventos y que llegan concurrentemente, por lo que se podría estar funciones. En general, los agentes son relativamente en dos funciones de callback a la vez, con la posibilidad compactos y, en el caso de los profilers, se dedican a de corromper las estructuras de datos que utiliza el recolectar información durante la vida de la aplicación agente. Sin embargo, JVMTI proporciona funciones para monitorizada. Los agentes, podrían ser controlados por el manejo de monitores que serán muy útiles para evitar un proceso a parte que implemente un front-end sin los problemas de exclusión mutua. interferir en la ejecución normal de la aplicación monitorizada. La Fig. 2 muestra un esquema de la La Tabla 1 muestra todos los eventos de JVMTI: arquitectura básica de un sistema que usa JVMTI: Tabla1: Eventos de JVMTI.

Breakpoint Method Entry Class File Load Hook Method Exit Class Load Monitor Contended Enter Class Prepare Monitor Contended Exit Compiled Method Load Monitor Wait Compiled Method Unload Monitor Waited Data Dump Request Native Method Bind Dynamic Code Generated Object Free Exception Single Step Exception catch Thread End Field Acess VM Death Field Modification VM Initialiation Frame Pop VM Object Allocation GC Finish VM Start

50 Actas del II congreso javaHispano

GC Start eventos se quieren atender así como de qué funciones harán de callback. Además JVMTI ofrece también un número elevado de funciones, se pueden solicitar eventos que se podrían clasificar tal y como muestra la Tabla 2. pasados, que no se Tabla 2: Clasificación de las funciones de JVMTI. pudieron atender. Capacidades Obtención de las Manejo de Reserva y liberación de (Capability) posibilidades que ofrece la Memoria memoria. No se deben usar implementación de JVMTI funciones tipo malloc. de la JVM usada. Activación Threads Obtener información de los y desactivación de esas hilos y controlarlos posibilidades para optimizar (suspender, interrumpir, el rendimiento. continuar, etc.). Además Temporizadores Utilidades para medir los permite crear hilos para el tiempos de CPU usados por agente, por ejemplo para los distintos hilos. La implementar un pequeño temporización es muy servidor que escuche en un utilizada en profiling. puerto. System Properties Obtener información acerca Grupos de threads Obtener información de los de la JVM usada. grupos de threads General Funciones varias. Stack Frame Obtener información de los registros de activación contenidos en la pila de cada hilo. 3 Pasos para la creación de un agente Montón (Heap) Recorrer el montón JVMTI llegando a los objetos. Posibilidad de invocar al Las posibilidades de JVMTI son mayores a las que se ven recolector de basura. en este artículo. Sin embargo, se exponen las tareas más Variables locales Acceder a las variables comunes para comenzar el desarrollo de un agente que locales para lectura y/o se adapte a las necesidades de cada caso. modificación. Puntos de ruptura Gestión de los puntos de (Breakpoints) ruptura. Orientado 3.1 Inicio del agente totalmente a depuración. Lo mínimo que debe tener un agente es la función Seguimiento de Seguimiento de una Agent_OnLoad, la cual es invocada cuando se carga la variables (Watches) variable, para detectar librería. En el momento en que se ejecuta esta función, cuando se lee o se modifica. la JVM no ha ejecutado todavía ningún bytecode, ni ha Clases Información completa cargado ninguna clase, ni ha creado ningún objeto. Las acerca de las clases, además tareas habituales que se realizan en esta función son: de la posibilidad de modificarlas (ver sección 4). • Especificar toda la funcionalidad que va Objetos Información básica de un necesitar con JVMTI. Esto se hace a través de objeto: hash code, tamaño funciones específicas que indican si la JVM que y uso de su monitor. se utiliza tiene disponibles las capacidades que Atributos (Fields) Información acerca de los se precisan en su implementación propia de atributos (fields) de las JVMTI. Estas funciones son las del tipo clases. *Capabilities. Existen capacidades que pueden Métodos Información acerca de los ser cambiadas durante la ejecución, aunque métodos de las clases. esto depende de la JVM. Monitores Manejo de monitores para • Solicitar los eventos de los que se quiere ser evitar problemas de notificado. Para ello están las funciones exclusión mutua, sobre relacionadas con los eventos, como por ejemplo todo en el acceso a la SetNotificationMode. Además se deberá indicar información que recolecta el un puntero a una función por cada evento, es agente. decir, especificar las funciones de callback. Intercepción de Mapear las funciones JNI a funciones JNI otras que se indiquen. Con • También se suelen iniciar las estructuras de ello se pueden capturar las datos que vaya usar el profiler, como tablas llamadas a dichas funciones hash que mantienen toda la información que irá realizadas por código nativo recogiendo el profiler: clases cargadas, objetos de usuario. creados, marcas de tiempo de entrada y salida Gestión de eventos Establecimiento de qué de métodos, etc.

51 Actas del II congreso javaHispano

El siguiente fragmento de código muestra una posible } implementación en C++ de la función Agent_OnLoad. ...

JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void 3.3 Compilación y ejecución del agente *reserved) { Para compilar el agente JVMTI se deben ejecutar los jvmtiEnv * jvmti; siguientes pasos: jvmtiCapabilities capabilities; jvmtiEventCallbacks callbacks; Considerando que el J2SE está en el directorio /jdk1.5.0 y que la plataforma es Linux, nos situaremos en el /* obtener el entorno JVMTI */ vm->GetEnv( (void **)&jvmti, JVMTI_VERSION); directorio de donde estén los ficheros fuente y ejecutaremos: /* exigir capacidades */ jvmti->GetCapabilities( &capabilities); >g++ –c –I/jdk1.5.0/incluye – capabilities.can_generate_all_class_hook_eve I/jdk1.5.0/include/linux *.c nts = 1; >g++ –shared –o libagent.so *.o jvmti->AddCapabilities( &capabilities); El agente quedará compilado en libagent.so. Para /* Establecer los punteros a las funciones ejecutar una aplicación Java que utilice el agente se callback vmInit y classFileLoadHook son dos deberán ejecutar los siguientes comandos (se considera funciones que se han definido previamente. que libagent.so está colocado en el mismo directorio que */ memset(&callbacks, 0, sizeof(callbacks)); la aplicación Java): callbacks.VMInit = &vmInit; callbacks.ClassFileLoadHook= >LD_LIBRARY_PATH=. &classFileLoadHook; >java –cp . –agentlib:agent Aplicacion jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)); /* Activar los eventos que queremos */ jvmti- 4 BCI: Bytecode Instrumentation >SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL); JVMTI no incluye muchos eventos que podrían jvmti- >SetEventNotificationMode(JVMTI_ENABLE, considerarse imprescindibles. Ejemplo de ello son los JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL); eventos de creación de un nuevo objeto de usuario, o eventos eficientes de entrada y salida de métodos. Sin return JNI_OK; embargo, JVMTI proporciona el soporte para BCI } (Bytecode Instrumentation), es decir, la posibilidad de alterar el bytecode del programa objetivo de 3.2 Atendiendo a un evento optimización. Antes de explicar cómo se puede utilizar esta técnica en JVMTI, se hará una breve introducción a Una vez inicializado, el trabajo del agente consistirá en la misma, cuyo uso es cada día más frecuente. atender a los eventos que le lleguen, actualizando sus datos y utilizando funciones, bien cuando llega un Se pude definir BCI como la técnica destinada a la evento o bien en otro momento, por ejemplo cuando se modificación directa de Bytecode Java. La mayor parte le solicita desde otro proceso que coopera con él. de las aplicaciones que usan BCI son herramientas de monitorización, profiling y de AOP (Aspect Oriented El siguiente ejemplo muestra un fragmento de código Programming). La intención es poder inyectar para atender al evento VM Object Alloc, que es enviado instrucciones en el código objeto (.class) del usuario en cuando la JVM crea un objeto que no es de usuario. Para lugares estratégicos o puntos significativos, como por los objetos de usuario se debe usar BCI, comentado en la ejemplo la entrada o salida de un método, para realizar sección 4. acciones generalmente de aviso.

/* Función de callback para los eventos VM La Figura 3 muestra cómo se modifica el código de Object Allocation */ usuario a la entrada y salida de un método para notificar static void JNICALL a rutinas de análisis. callbackVMObjectAlloc(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, jobject object, jclass object_klass, jlong size) { ... char *className; ... if (size > 50) { jvmti->GetClassSignature(jvmti, object_klass, &className, NULL); if (className != NULL) { printf("\nSe ha creado un objeto de la clase %s que ocupa %d\n", className, (jint)size);

52 Actas del II congreso javaHispano

son puramente adiciones, no modifican el estado o comportamiento de la aplicación. El hecho de que la inserción se haga en estándar bytecode, implica que la JVM puede ejecutarse rápidamente. El resultado es que se habrán generado eventos muy eficientes. Esta aproximación proporciona además un control total por parte del agente, ya que la inserción de código podría restringirse a porciones muy concretas del programa (por ejemplo, sólo código de usuario, no de librerías estándar o de sistema). Una vez que se produzca el evento, se puede tratar en código Java o redirigir el evento hacia el agente nativo. La Figura 4 muestra un ejemplo de inserción de bytecode en código de usuario para ser tratado después por el agente.

Figura 3: Uso de BCI para detectar llamadas a métodos. Un ejemplo muy ilustrativo se tiene en AOP que, en líneas muy generales, consiste en interceptar el código de usuario en lugares concretos (join-points), para ejecutar el código arbitrario que implementa el aspecto (advice). Esto se consigue añadiendo el código necesario en la zona de usuario, que provoque una llamada al código que implementa el aspecto. De esta tarea se encarga en general el compilador de AOP.

Existen numerosos productos que usan esta técnica. Por ejemplo, software orientado a la monitorización de Figura 4: Inserción de bytecode en una clase de usuario. sistemas como Wily Technology – Introscope, HP La manipulación de bytecode puede ser llevada a cabo OpenView Transaction Analyzer, la mayor parte de los en tres momentos distintos: profilers como OptimizeIt, JProfiler, JProbe y herramientas AOP como AspectJ y AspectWerkz. • Estáticamente: se trata de modificar los ficheros .class antes del momento de la ejecución, como Para desarrollar una aplicación que necesite usar BCI, se suele hacer en AOP. Esta opción no es muy existen también librerías, muchas de libre distribución, útil JVMTI. como por ejemplo BCEL (Apache Bytecode Engineering Library), BIT (University of Colorado – Bytecode • En el momento de carga. La modificación se Instrumenting Tool), ej-Technologies – jclasslib, etc. produce justo antes de la carga de la clase. Para Todas ellas son librerías Java que permiten la ello JVMTI proporciona el evento manipulación de ficheros .class y su transformación. ClassFileLoadHook, que avisa cada vez que una clase está a punto de cargarse, proporcionando Además de las librerías anteriores, se dispone de la oportunidad de modificarla. Esto ya existía en java_crw_demo (Java Class Read-Write Demo), incluida JVMPI. en J2SE 5.0 como una librería dinámica (.dll o .so). La aparición de JVMTI viene, por tanto, acompañada de • Dinámicamente. La modificación de la clase se esta librería. De hecho, el conocido profiler hprof que se realiza una vez cargada la clase, en cualquier distribuye con el J2SDK, hace uso de ella ya que fue momento posterior, incluso habiendo sido migrado de JVMPI a JVMTI. java_crw_demo ofrece ejecutada ya. Para ello, JVMTI proporciona la funciones básicas para la manipulación de bytecode, función RedefineClasses. Esta funcionalidad no suficiente en muchos casos para la mayoría de las existía en JVMPI. implementaciones. De ella se hablará en el siguiente El evento ClassFileLoadHook y la función RedefineClasses apartado. es todo lo que proporciona JVMTI para realizar BCI. Es decir, da la oportunidad de realizar modificaciones, pero 4.1 BCI en JVMTI no realiza la modificación en sí, es responsabilidad del programador del agente JVMTI trabajar a nivel de Las alteraciones más comunes que se hacen en el bytecode con cada clase. Es por ello por lo existe la bytecode de usuario con BCI son la inclusión de librería dinámica java_crw_demo mencionada “eventos” al código de un método, como por ejemplo, el anteriormente, que permite realizar unas modificaciones añadir al comienzo de un método la llamada a básicas sobre el código de una clase. MiProfiler.metodoLlamado(). Debido a que estos cambios

53 Actas del II congreso javaHispano

Las inserciones de bytecode que java_crw_demo realiza en una clase provocan una llamada hacia una clase y método que se le indique. Estas inserciones se pueden hacer hasta en cuatro lugares distintos:

• En el constructor de java.lang.Object: con ello se puede capturar la creación de cualquier objeto, ya que todos pasan obligatoriamente por este método. Es decir, se habrá recuperado un evento disponible en la antigua JVMPI, que ahora no hay: JVMPI_EVENT_OBJECT_ALLOC.

• A la entrada de todos los métodos de la clase indicada.

• A la salida de todos los métodos de la clase indicada.

• Inmediatamente antes de cualquier creación de un array. Con ello se puede capturar el momento de la creación de un objeto array.

5 Migrando JVMPI a JVMTI. Un ejemplo práctico: JavaTraceIt! En esta sección se muestra un ejemplo real de la migración de un profiler de JVMPI a JVMTI. JavaTraceIt! implementa un depurador y optimizador de código libre para Java. Fue presentado en el I Congreso JavaHispano de 2003. JavaTraceIt! consta de dos partes bien diferenciadas. Por un lado implementa un depurador que permite realizar la ejecución paso a paso del código, el establecimiento de puntos de ruptura y la inspección/modificación de las variables en memoria. El depurador ha sido desarrollado con JPDA (ver apartado 1.1). Por otro lado, implementa un profiler con un analizador de memoria que permite visualizar las clases cargadas, el número de instancias de cada clase y los bytes ocupados por los objetos de cada clase. Figura 5: El profiler de JavaTraceIt!. La Figura 5 muestra una captura de JavaTraceIt! y de su El profiler de JavaTraceIt! había sido desarrollado profiler en ejecución. inicialmente con JVMPI, la única alternativa disponible cuando se implementó. La desaparición anunciada de JVMPI a favor de JVMTI ha motivado la migración del profiler a la nueva interfaz. A continuación se explican los pasos más relevantes en el trabajo realizado. La arquitectura del sistema de profiling de JavaTraceIt! es muy similar a la que se muestra en la Figura 2. JavaTraceIt! presenta un front-end como se puede apreciar en la Figura 5. En el antiguo sistema de profiling, había un agente JVMPI que corría en el mismo proceso que la JVM de la aplicación monitorizada. Su trabajo se dividía en dos partes:

• Capturar los eventos necesarios para elaborar las tablas donde se guardaban las clases cargadas, número de instancias y bytes ocupados.

• Atender las peticiones desde el front-end a través de un protocolo propio. Estas peticiones podían ser la solicitud de las tablas para

54 Actas del II congreso javaHispano

mostrarlas gráficamente y la ejecución del Para la captura de la creación de arrays, también se recolector de basura. Para ello, el agente inyecta código en todos los métodos de las clases implementaba un pequeño servidor a través de cargadas donde se crea un array. Dicho código introduce sockets por el que se recibían las órdenes y se una llamada a Tracker.NewArray(). devolvían los datos de las tablas. El siguiente fragmento de código corresponde a la clase Debido a la existencia de un protocolo propio que Tracker: separaba el front-end del agente, no ha sido necesario tocar el front-end, simplemente se exige que el nuevo public class Tracker { agente JVMTI implemente el mismo protocolo. /* Para contar el numero de instancias se La migración del servidor ha sido muy sencilla. Lo único necesita capturar la creacion de objetos y que se requería era la capacidad de JVMPI de de arrays.*/ proporcionar un hilo nuevo para que se pudiese ejecutar atendiendo peticiones. JVMTI tiene también esa /* Al principio de java.jang.Object.(), se inyecta una capacidad con la función RunAgentThread. llamada a Tracker.ObjectInit().*/ private static native void El trabajo con los eventos no ha sido tan sencillo como el nativeObjectInit(Object thr, Object obj); caso anterior. Los eventos más importantes que atendía el agente con JVMPI eran los siguientes: public static void ObjectInit(Object obj) { • JVMPI_EVENT_CLASS_LOAD (carga de una …

clase). Cuando se cargaba una clase se creaba nativeObjectInit(Thread.currentThread(), una nueva posición para ella en las tablas hash. obj); … • JVMPI_EVENT_OBJECT_ALLOC (creación de un } objeto). Cuando se creaba un objeto se consultaba de qué clase era y se incrementaba /* Inmediatamente despues del bytecode en uno el número de instancias de esa clase. newarray, se inyecta una llamada a Tracker.NewArray(). */ • JVMPI_EVENT_OBJECT_FREE (eliminación de un private static native void objeto). Cuando se eliminaba el objeto se nativeNewArray(Object thr, Object obj); averiguaba si estaba guardado, ya que uno de public static void NewArray(Object obj) los problemas de JVMPI es que no avisaba de { todas las creaciones de objetos, por lo que … podía avisar de la liberación de objetos de los cuales no había sido informada su creación. Si nativeNewArray(Thread.currentThread(), obj); no se tenía registrado, no se hacía nada, en … } caso contrario se restaba uno al número de instancias de su clase. Como se puede observar en el fragmento de código anterior, existen métodos nativos a los cuales se invoca

desde las funciones ObjectInit y NewArray. Estos La migración de JVMPI_EVENT_CLASS_LOAD no ha métodos están también implementados y registrados en supuesto ningún problema ya que existe su equivalente el agente, es decir, cuando se llaman el control lo toma en JVMTI. el agente para que pueda actualizar sus tablas. El problema más importante lo presenta sobre todo el Por último, el evento JVMPI_EVENT_OBJECT_FREE, evento de JVMPI_EVENT_OBJECT_ALLOC que, como se proporciona uno similar en JVMTI. La diferencia que ha mencionado en la sección 4, no existe equivalente en existe es que en JVMTI el evento no llega para todos los JVMTI. Para conseguir de nuevo ese evento ha sido objetos, sino que solamente para aquellos objetos necesario incluir BCI, es decir, modificar el Bytecode de “marcados” (tagged). JVMTI permite establecer una las clases. Para ello se utiliza la librería java_crw_demo marca a cualquier objeto (un jlong) a través una función. como se explica en el apartado 4.1. Con esto se evita que llegue este evento sobre un objeto del que el agente no tiene información de su existencia, La idea consiste en modificar la clase java.lang.Object problema que presentaba JVMPI. incluyendo al comienzo del constructor una llamada a un método estático de una clase propia: Tracker.ObjectInit(). Por lo tanto, cada objeto creado 6 Conclusiones invocará al construirse a este método. Esta idea es la misma que sigue el profiler hprof cuyo código fuente En la actualidad la demanda de profilers Java está en está disponible. El código de la clase Object se realiza aumento. La enorme carga transaccional que pueden justo cuando se carga. Se utiliza por tanto el evento llegar a tener las aplicaciones J2EE puede generar ClassFileLoadHook, que es el mecanismo que ofrece problemas en producción. Es por ello que las JVMTI para poder realizar BCI. Una vez que la función herramientas de monitorización, como son los profilers, Tracker.ObjectInit() se invoca, se transfiere el control a pueden ser de gran ayuda en esas situaciones. Con través de JNI al agente. JVMTI, la plataforma Java ya dispone de una interfaz estándar para desarrollar este tipo de aplicaciones, que

55 Actas del II congreso javaHispano permitirá a los desarrolladores no sólo comerciales el poder crear sus propias utilidades para la monitorización y optimización de las aplicaciones Java, de un modo sencillo y eficiente. La transformación que ha sufrido la antigua API JVMPI hacia JVMTI ha traído consigo ventajas ya mencionadas en el presente trabajo, aunque obligue al uso de BCI en la mayor parte de los casos. Sin embargo esta evolución está justificada ya que esta técnica permite la creación de profilers muy eficientes, restricción básica en este tipo de herramientas.

Referencias

[1] Sun Microsystems. JVM Tool Interface v.1.0. http://java.sun.com/j2se/1.5.0/docs/guide/jvmti/jvmti.html. [2] Sun Microsystems. The Java Virtual Machine Profiler Interface (JVMPI). http://java.sun.com/j2se/1.4.2/docs/guide/jvmpi/jvmpi.html [3] C.K. Prasad, Rajesh Ramchandani, Gopinath Rao, y Kim Levesque. Creating a Debugging and Profiling Agent with JVMTI. http://java.sun.com/developer/technicalArticles/Programmi ng/jvmti/ [4] Kelly O’Hair. The JVMPI Transition to JVMTI. http://java.sun.com/developer/technicalArticles/Programmi ng/jvmpitransition/ [5] Sun Microsystems. Java Platform Debugger Architecture (JPDA). http://java.sun.com/products/jpda/index.jsp. [6] Joseph Coha y David Seidman. Bytecode Instrumentation – Making it simple. JavaOne 2004. http://www.hp.com/products1/unix/java/pdfs/bytecode.pdf [7] Han Bok Lee. BIT: Bytecode instrumenting tool. University of Washington, 1996. http://www- plan.cs.colorado.edu/hanlee/pubs/master.pdf [8] Apache Software Foundation. BCEL: Bytecode Engineering Library. http://jakarta.apache.org/bcel/index.html. [9] Ej-Technologies - jclasslib. http://www.ej- technologies.com/products/jclasslib/overview.html [10] D. Glez-Peña, F. Fdez-Riverola. JavaTraceIt: Depurador y optimizador de aplicaciones Java. I Congreso javaHispano, Madrid, España, Octubre 2003. http://congreso.javahispano.org/files/doc/j2se/JavaTraceIt_d epurador_y_optimizador.pdf

56 Actas del II congreso javaHispano

JNIEasy, Aspect Oriented Programming a la ayuda de Java como ciudadano de primera clase en el desktop

Jose María Arranz Santamaría [email protected] [email protected]

Pero no nos engañemos, Java al igual que la plataforma Abstract LAMP tiene su relevancia fundamentalmente en

Las necesidades en el desktop son habitualmente mucho aplicaciones basadas en Web y especialmente en gestión más complejas y diversas que en el servidor, las de bases de datos. Este papel muy relevante en el Web aplicaciones normalmente necesitan acceder directamente a se debe a varios factores entre otros: recursos hardware o servicios del sistema operativo no 1) La portabilidad de Java entre sistemas necesariamente cubiertos por el Java estándar, con los que se consigue una mayor integración con el sistema y una En un mundo, el del servidor, en donde Linux y otras mayor familiaridad para el usuario. Este problema ha sido plataformas Unix han tenido un gran papel al ofrecer resuelto por Java programando con lenguajes nativos tradicionalmente potencia y robustez. Y siguen (C/C++) usando el complejo JNI y necesitando un teniéndolo gracias en parte a Java y a la explosión de compilador o un IDE. La realidad muestra que buena parte servicios y comercio electrónico basados en Web que nos de los desarrolladores de Java no conocen C/C++. trajo la burbuja tecnológica. El papel de JDBC ha sido JNIEasy[1] es una herramienta que permite la interacción fundamental permitiendo una conectividad con bases de con librerías nativas (DLLs) para acceder directamente datos más estandarizada y portable que las soluciones desde Java a recursos del S.O. o a hardware especializado basadas en ODBC, y OleDB. sin necesidad de programar con JNI, C o C++. Los 2) La portabilidad de las tecnologías Web y la casi programas desarrollados con JNIEasy serán 100% Java, independencia tecnológica entre el cliente y el pudiendo llamar desde Java a métodos nativos contenidos servidor en DLLs, exponer automáticamente métodos de clases normales a llamadas desde código nativo (callbacks), definir Por ejemplo, nada impide que Java en un servidor no “estructuras nativas” como simples clases, y gestionar la Windows produzca HTML transmitido por HTTP “memoria nativa” de forma automática con el garbage consumido en Windows por el Internet Explorer. collector. Las soluciones existentes hasta ahora no han 3) La calidad, fiabilidad, seguridad, robustez y conseguido una solución tan transparente y céntrica en capacidad de gestión de la complejidad que ofrecía Java, gracias a la Aspect Oriented Programming y el Java como plataforma frente a soluciones más bytecode enhancement. “amateur” como ASP o PHP, o frente a la inseguridad y complejidad que ofrece C/C++ poco Keywords: Java, JNI, AOP, bytecode enhancement, C, C++, DLL, transparencia apto para el mundo esencialmente “concurrente” que exige el Web. 1 El dominio casi absoluto de las 4) La “familiaridad” de Java con las tecnologías tecnologías Windows en el desktop subyacentes a Internet (http, applets, RMI etc) De todos es sabido la enorme penetración que tiene Java 5) La aparición de una pléyade de frameworks en el mundo del software, Java es sin duda una de las orientados fundamentalmente a simplificar el tres plataformas relevantes de desarrollo software desarrollo Web y la manipulación de bases de datos, actualmente junto con .Net y LAMP desde los estandarizados (J2EE=JSP+EJB, JSF, JDO) (Linux+Apache+MySQL+Perl/PHP). con versiones libres y comerciales, hasta los

57 Actas del II congreso javaHispano

populares de código abierto como Struts, Hibernate, de pastel al mundo Microsoft/Intel (aunque ahora el reto Spring etc. también está contra Linux/Intel).

Sin embargo todo cambia cuando lo vemos desde el El WORA es un hecho en el lado del servidor, pero está punto de vista de los sistemas orientados a ser usados todavía lejos de conseguirse en el desktop. El terreno del como puesto de trabajo individual es decir el llamado desktop está lleno de “piedrecitas” en donde una desktop o escritorio. solución relativamente sencilla en C, C++, Visual Basic ¡y ahora en .Net!, puede ser un verdadero “pain in the ass” Varios hechos: en Java, cuando ha de accederse directamente al sistema 1) Windows está instalado en más del 90% de los operativo o al hardware, y no siempre estamos hablando computadores del mundo [2] de necesidades de alto rendimiento que justifiquen JNI.

2) La gran mayoría de aplicaciones Windows En este sentido Java está hoy día en una encrucijada: o orientadas al desktop están desarrolladas con conquista un aceptable territorio en el desktop o puede tecnologías Microsoft (Visual C++, Visual Basic) perder definitivamente esa batalla (como la perdió sean aplicaciones de Microsoft o no. Borland con C++ y Delphi), en la medida en que .Net es un competidor directo de Java, obviamente se integra 3) Windows está fuertemente componentizado, muy bien con Windows, no es un juguete para amateurs normalmente a través de dichos componentes como en cierto modo era Visual Basic, ni tan complejo e accedemos a los recursos del hardware o a los inseguro como era el Visual C++. servicios del sistema operativo. En esta guerra hay muchos factores, ciertamente se 4) La API primaria con la que Windows se “expone” es necesita mucho más WORA pero quizás también una C (Platform SDK), las demás son capas sobre ésta visión más pragmática y menos exigente a corto plazo: (incluido el COM). El SDK C es gratuito. más “Java for Windows only”, huyendo de la “palabra 5) Los drivers propietarios que acceden a los recursos maldita” que hace inclinar la balanza por el universo del hardware exponen prácticamente siempre una Microsoft: JNI interfaz C o COM.

Java ha hecho un gran esfuerzo por ofrecer una “capa” 3 JNI amigo y enemigo Java para cualquier necesidad permitiendo una La programación en lenguajes nativos es más compleja integración portable con el S.O., pero la experiencia dice que con Java y menos robusta, JNI es relativamente que no siempre es posible “esperar” que Sun (o en complejo como mezcla de dos mundos (Java y nativo) general el ecosistema Java) lo haga, pues obviamente pues supone programar “en Java” pero con C/C++. Microsoft siempre irá delante en sus propias tecnologías. Cuando se realiza una aplicación Java con JNI siempre Esfuerzos como el JDIC[3] o el JMF[4] son encomiables, existe la lucha entre si más Java o más C/C++, el pero en el caso del JMF, un componente tan básico, modelar dos veces, la conversión de datos etc. De hecho todavía no tiene lugar en el JRE y su licencia es todavía no es raro que el resultado sea una aplicación basada en demasiado restrictiva. código nativo fundamentalmente y una fina capa Java.

De todas formas existen infinidad de casos no típicos, El problema no es el JNI en sí mismo, JNI tiene el normalmente acceso a hardware propietario, en donde importantísimo papel de no permitir que Java sea una es difícil esperar una solución estándar, ni siquiera del plataforma cerrada. En algunas aplicaciones en donde se propio fabricante, el “háztelo tu mismo si puedes” es la necesita una comunicación íntima con el hardware con regla. alto rendimiento es insustituible, pero es sin duda una de las grandes piedras que se encuentra Java en el 2 WORA, realidad y utopía desktop: cuando es la única alternativa para problemas que no resuelve Java (es decir, que otros todavía no han El WORA (Write Once Run Anywhere) es la utopía resuelto con JNI). deseada por Sun (y competidores en el mismo “lado”) para poder vender más hardware y arrebatar un trozo Ejemplo ilustrativo: Sourceforge.net, el inmenso repositorio de aplicaciones de código abierto, Java goza

58 Actas del II congreso javaHispano

de muy buena salud (ver Tabla 1, muchos de los El bytecode enhancement es AOP en su sentido más proyectos es sabido que combinan C y C++ y el propio primitivo, consiste en la introducción de código nuevo Java por lo que no son “sumables”). Java, precompilado, directamente en las clases a nivel de bytecode, así como la modificación de código ya Tabla 1: Lenguajes en Sourceforge existente. A través de esta técnica se consigue el objetivo Lenguaje Proyectos de la AOP de resolver de forma elegante (ortogonal) los Java 13274 llamados crosscutting concerns, en síntesis, tareas o C 13807 problemas que no pueden expresarse de forma directa a C++ 14117 través de una clase base o derivada o por agregación, y Visual Basic 1977 que su resolución por las técnicas habituales supone la C# 1976 diseminación de pedazos de código similares por Sin embargo filtremos la categoría: Multimedia / Vídeo y multitud de puntos del programa de forma fuertemente con combinaciones de lenguajes entre Java, C y C++ intrusiva. (Fig. 1). A través de bytecode enhancement podemos acometer en síntesis los objetivos de la AOP:

1) Añadir nuevos métodos y atributos a una clase preexistente

2) Introducir llamadas a los nuevos métodos (advices) en ciertos puntos del código original Figura 1: Sourceforge, lenguajes en proyectos de vídeo (pointcuts) dentro del conjunto de puntos de (noviembre de 2004) unión posibles (joinpoints)

Tabla 2 El conjunto de nuevas funciones (advices), atributos y Lenguaje Proyectos poincuts orientados a realizar una cierta tarea es lo que Java sin C o C++ 10 se denomina en AOP aspecto.

Java con C o C++ 13 En JNIEasy no se utiliza ningún framework AOP concreto, C o C++ sin Java 87 sino que se utiliza directamente bytecode enhancement, la razón hay que buscarla en la gran libertad de De acuerdo con la Tabla 2 podemos concluir que Java no manipulación que permite respecto a usar un framework es muy relevante en áreas como la manipulación de concreto, pues todo framework al mismo tiempo que vídeo, tarea típica de desktop, y lo normal es que venga supone una formalización elegante de un servicio, acompañado de programación en lenguajes nativos (JNI supone al mismo tiempo la introducción de limitaciones, con gran probabilidad). la analogía hay que encontrarla por ejemplo entre programar en C o en ensamblador. De todas formas no 4 Aspect Oriented Programming y el está descartado introducir en el futuro un framework, bytecode enhancement seguramente AspectWerkz, más flexible que AspectJ.

Aunque no son filosofías y tecnologías nuevas, es en este La razón de usar bytecode enhancement es una absoluta momento cuando están teniendo un gran auge, en necesidad, sin el mismo no sería posible conseguir el concreto la AOP, pero hablar de AOP en Java casi no es nivel de transparencia que ofrece JNIEasy, la alternativa posible sin el bytecode enhancement, los dos es usar las técnicas claramente intrusivas “y poco Java” frameworks más relevantes: AspectWerkz y AspectJ que han acompañado hasta ahora las aproximaciones están basados en esta técnica (existen otras como los clásicas al problema. proxies dinámicos, usados en Spring, pero el alcance de posibilidades es menor), ambos vienen a ser la expresión formal y bien estructurada de los conceptos de la AOP, y de las posibilidades que permite el bytecode enhancement.

59 Actas del II congreso javaHispano

5 JNIEasy hacia una solución Java sin JNI Sea la definición de una estructura:

// C: struct TestStruct { short a; int b;}; 5.1 Estrategias de diseño private static class TestStruct La finalidad de JNIEasy es muy simple: sustituir a JNI, es extends Structure { decir, ser un nuevo Java Native Interface pero basado public Int16 a = new Int16(); totalmente en Java desde el punto de vista del public Int32 b = new Int32(); programador. De esta manera conseguimos eliminar la public TestStruct() { problemática mezcla de C/C++ y Java. init(new Parameter[] {_int16,_int32});} } Hay dos aproximaciones o estrategias al problema: Aparte de lo intrusivo que supone la necesidad de 1) Crear un modelo Java que represente los tipos de derivar de la clase Structure, tampoco nos ofrece una datos, las instancias y la forma de manipular la natural simetría ni con una clase Java con dos atributos memoria de un programa en C short e int ni con la propia estructura C original.

2) Vincular la forma “normal” de manipulación y tipos Veamos la definición de una callback: una callback en C de datos de Java a la manipulación nativa es una función diseñada para ser llamada normalmente desde dentro de otra función en donde la dirección de JNIEasy utiliza la segunda estrategia y el resultado es una memoria de la callback ha sido dada como argumento: mayor transparencia y familiaridad. /* C callback: int callback(int); */ Analicemos la primera opción con varios ejemplos private static class IncIntCallback tomados de otro producto con similar objetivo [5]: extends Callback { Int value = new Int(); // int private Int _arg = new Int(); Pointer pValue=new Pointer(value); // int* private Int _result = new Int(); public IncIntCallback() { En este ejemplo se hace una correspondencia directa init(new Parameter[] {_arg},_result);} entre el tipo de datos nativo C int con un objeto Java, public void callback() { la instanciación de un objeto Int vendría a ser como la _result.setValue(_arg.getValue()+1);} declaración C de una variable (int value; por } ejemplo). A continuación se crea un objeto Pointer que Como se puede comprobar los parámetros “formales” de albergará la dirección de memoria que apunta al dato la función están expresados como atributos de la entero value. Como vemos se identifica un objeto Java callback, expresada como una clase Java. Dichos por cada dato nativo correspondiente que se quiere atributos recibirán los valores de la llamada cuando se poner en memoria. produzca y el resultado se pondrá en un atributo específico. Veamos una llamada a función: La consecuencia de éste enfoque es código Java que no // int sprintf(const char*,…); C parece Java” ni siquiera programación C. Function sprintf = new Library("msvcrt") .getFunction("sprintf"); El desarrollo de JNIEasy tuvo en cuenta este problema AnsiString result = new AnsiString(); desde el principio, de ahí que uno de los principales sprintf.invoke(null,result, principios rectores fuera no tanto expresar en Java el new AnsiString("Hello, %s!"), modelo nativo C sino más bien lo contrario corresponder new AnsiString("World")); el modelo de trabajo normal de Java con el modelo System.out.println(result.getValue()); nativo. Para ello JNIEasy emplea un arsenal de técnicas //Output: Hello, World! desde la AOP via bytecode enhancement, código C y C++ con JNI, ensamblador e incluso generación Como se puede observar las cadenas que se pasan como dinámica de código máquina. parámetros se envuelven en objetos especiales Punto de vista de JNIEasy: AnsiString y el retorno también cadena es pasado como parámetro. String cadena = new String("Texto");

60 Actas del II congreso javaHispano

mismo puede decirse para los demás tipos básicos long, Representa en JNIEasy desde el punto de vista nativo a byte, char etc), por eso es también válido llamar como: una cadena de caracteres (char) acabada en un nulo Integer hwndObj = (Integer)method.call(new ('\0') instanciada en memoria a la que apunta un Object[] {null,"DDE Server Window"} ); puntero (de tipo const char*) que equivale a la referencia String cadena en Java. Aunque el objetivo En donde el método “call” es agnóstico en el tipo de no se consigue 100% el alcance conseguido es retorno (debe ser Object). probablemente el más alto de las herramientas disponibles. Sólo es necesario obtener una sola vez el objeto que representa el método, a cambio en todas las llamadas los Lo demostraremos a continuación con ejemplos que nos parámetros son supervisados comprobando que sean del servirán para descubrir la “naturalidad” de uso y las tipo adecuado, lo cual da una robustez mayor que la que capacidades de JNIEasy. ofrece la misma llamada en lenguaje nativo.

5.2 Llamadas a funciones Es recomendable y más cómodo poner todas las funciones de una DLL en una clase al efecto: Consideremos la siguiente función de la API Win32: public class User32 { HWND FindWindow( public static DynamicLibrary dll LPCTSTR lpClassName, // class name = JNIEasy.getInstance(). LPCTSTR lpWindowName ); // window name getDLLManager().get("User32.dll"); public static GenericMethod[] methodList Su finalidad es devolver el handler de la ventana cuya = new GenericMethod[…]; clase y nombre (título) vienen dados por dos cadenas, la static { clase es opcional y puede ser NULL. methodList[0] = JNIEasy necesita conocer cómo es dicha función para dll.addCMethod("FindWindowA",... ); poder convertir la llamada Java en llamada nativa: ... } public static int findWindow(String JNIEasy.getInstance().load(); className,String windowName) { DynamicLibrary user32DLL = CMethod method = (CMethod)methodList[0]; JNIEasy.getInstance().getDLLManager().get( return method.callInt(new Object[] "User32.dll"); { className, windowName} ); CMethod method = } . . . user32DLL.addCMethod("FindWindowA", Conscientes de que esta es una tarea tediosa, JNIEasy int.class, // tipo de retorno dispone de un generador de código Java a partir de una new Class[] { sucinta descripción de los métodos en XML. Ejemplo de String.class, // nombre clase fragmento de declaración en XML: String.class }, // nombre ventana CallConv.STD_CALL ); {null, "DDE Server Window"} ); Notar que utilizamos directamente un objeto String como argumento al igual que el null análogo al NULL 5.3 Polimorfismo en funciones en C (y no un Pointer() cuyo contenido sea un nulo según la anterior estrategia). El dato devuelto es un int Cualquier programador en C conoce que aunque no es lo que nos simplifica la programación y evita la válido el polimorfismo de funciones en C, el lenguaje es necesidad de objetos especiales, de hecho cuando es lo suficientemente débil en su tipado para permitir un necesario manejar int como objeto (como argumento cierto grado de polimorfismo. por ejemplo) JNIEasy usa el tipo básico Integer (lo

61 Actas del II congreso javaHispano

Por ejemplo, en el caso de un puntero a cadena de retorno) es ANSI o Unicode cambiando el tipo de datos caracteres, const char*, aunque nuestra del parámetro (o retorno). Para ello se dispone de las correspondencia “natural” en Java es un objeto String interfases StringAnsi y StringUnicode: o StringBuffer, la cabecera de la función C admite CMethod method = jniEasyDLL.addCMethod( realmente como parámetro un entero, la dirección de "FindWindowW",int.class, memoria de la cadena. new Class[] { JNIEasy evita la simplificación de identificar nombre de StringUnicode.class, // class name función nativa – función Java , usando la más compleja StringUnicode.class }, // window name idea de “signatura” de función tal y como se emplea en CallConv.STD_CALL); C++ o Java para el polimorfismo de funciones: dos int hwnd = method.callInt(new Object[] funciones son diferentes si cambia el nombre o el tipo de {null, "DDE Server Window"} ); alguno de los parámetros. Aunque este método “espera” objetos StringUnicode Por tanto sería válido añadir un nuevo método: como parámetros, JNIEasy sabe que los objetos String CMethod method = user32DLL.addCMethod( son compatibles, el resultado será una llamada a la "FindWindowA",int.class, versión Unicode de FindWindow usando cadenas en new Class[] { Unicode. int.class, // nombre clase int.class }, // nombre ventana 5.5 Callbacks CallConv.STD_CALL ); Es posible programar callbacks en Java, funciones en Pudiendo usar enteros (direcciones de memoria) para Java que serán llamadas directamente desde código indicar las cadenas. nativo como si fueran funciones nativas.

Igualmente es posible obtener referencias a los métodos Veamos un ejemplo: Win32 dispone de una función registrados con el mismo nombre: EnumWindows que enumera a través de una callback todas las ventanas presentes en el desktop. List methods = user32DLL.findMethods("FindWindowA"); BOOL EnumWindows( WNDENUMPROC lpEnumFunc, /* callback */ u obtener el método exacto indicando la signatura a LPARAM lParam); /* app-defined value */ través de un objeto Signature : El tipo WNDENUMPROC se define a su vez como un tipo CMethodSignature sig = puntero a función cuyo prototipo es el siguiente: SignatureUtil.newCMethodSignature(int.class ,new Class[]{String.class,String.class}); BOOL CALLBACK EnumWindowsProc( method = user32DLL.findCMethod( HWND hwnd, // handle to parent window "FindWindowA", sig); LPARAM lParam ); // app-defined value

5.4 Unicode Una callback se define con JNIEasy como una clase que deriva de CCallbackImpl (en el caso de C), que El uso del Unicode está cada vez más generalizado y implementa el método: Object onCall(Object[] soportado por las herramientas software: los lenguajes params), dicho método es el que será llamado cuando modernos como Java lo soportan nativamente, C y C++ la callback sea invocada desde código nativo. incorporan caracteres Unicode (wchar_t de 16 bits) y la API Win32 tiene todas las funciones que usan cadenas public class EnumWindowsProc con dos prototipos: ANSI (terminadas en A) y Unicode extends CCallbackImpl { (terminadas en W). private static final CMethodSignature SIGNATURE = JNIEasy es por defecto ANSI pero puede usarse Unicode SignatureUtil.newCMethodSignature( como codificación por defecto o explícita. int.class,new Class[] Voluntariamente podemos indicar que un parámetro (o

62 Actas del II congreso javaHispano

{int.class,int.class}, "enumWindows", CallConv.STD_CALL ); new Class[]{int.class,int.class} ); public EnumWindowsProc() { CCallback callback = super(SIGNATURE); } CallbackUtil.newCCallback(reflMethod); public Object onCall(Object[] params) { method.callInt(new Object[]{callback, int hwnd = new Integer(10)}); ((Integer)params[0]).intValue(); int lParam = 5.6 Estructuras ((Integer)params[1]).intValue(); La definición de estructuras es donde JNIEasy se System.out.println("handle:" + hwnd + distancia claramente de las soluciones existentes, y en " param:" + lParam); donde entra a fondo la AOP y el bytecode enhancement. return new Integer(1); } Con ambas técnicas conseguimos “extender” una clase } normal Java para que represente a una estructura nativa, Invocaríamos EnumWindows por ejemplo: introduciendo de forma ortogonal, el “aspecto” de la method = user32DLL.addCMethod( gestión de los atributos para que representen a la "EnumWindows",int.class, imagen de una estructura C. new Class[] { Ejemplo, sea la estructura Win32 C: EnumWindowsProc.class, int.class }, CallConv.STD_CALL ); typedef struct tagPAINTSTRUCT { method.callInt(new Object[]{ HDC hdc; // HDC = int en Win32 new EnumWindowsProc(),new Integer(10)}); BOOL fErase; // BOOL = int en Win32 RECT rcPaint; Salida por pantalla: BOOL fRestore; BOOL fIncUpdate; handle:65784 param:10 BYTE rgbReserved[32]; handle:328538 param:10 ... } PAINTSTRUCT, *PPAINTSTRUCT;

Mientras el objeto callback esté en memoria es como si En Java: la función “se creara” desde el punto de vista nativo, cuando se pierde vía garbage collector pasa a ser public class PaintStruct { inaccesible (como si se destruyera código máquina) int hdc; liberando automáticamente sus recursos. El número de int fErase; callbacks en memoria es ilimitado. Detrás de las callbacks Rect rcPaint = new Rect(); // Es embebido de JNIEasy está una compleja mezcla de JNI, Java y int fRestore; código máquina generado dinámicamente desde Java. int fIncUpdate; byte[] rgbReserved = Existe la posibilidad de que la definición de la función new byte[32]; // Es embebido que define una callback sea autónoma de JNIEasy, para } ello se usa Java Reflection, en donde un objeto callback Rect sería una simple clase Java con cuatro enteros interno de JNIEasy “representa” la función “normal” de como atributos. En un archivo XML se indicaría además Java. Sea por ejemplo: que el atributo rcPaint y rgbReserved son public class EnumWindowsProc2 { embebidos (no RECT* o BYTE*). Finalmente la public static int enumWindows( sentencia: int hwnd, int lParam) { PaintStruct ps = new PaintStruct(); System.out.println("handle:" + hwnd + " param:" + lParam); supone la reserva en “memoria nativa” de una estructura return 1; } C equivalente, la referencia ps puede usarse en aquellas } funciones donde se pida un PAINTSTRUCT*. Si se java.lang.reflect.Method reflMethod = modifica desde Java hdc, por ejemplo, se modifica EnumWindowsProc2.class.getDeclaredMethod(

63 Actas del II congreso javaHispano

también en la memoria nativa, un programa C/C++ // signatura de la callback Java puede modificar ¡en cualquier momento! (no sólo __int64 (__stdcall *suma)(int,int); dentro de una llamada iniciada desde Java) el atributo suma = (__int64 (__stdcall *)(int,int)) hdc , percibiendo ese cambio en Java cuando se acceda findCBAddress(sig); al mismo. La interacción transparente memoria Java- __int64 res = suma(1,2); memoria nativa es una de las características más avanzadas de JNIEasy. llama desde código nativo al método Java exportado como si fuera un método C “normal”. Por supuesto el ciclo de vida de la estructura vista desde C es el mismo que el objeto Java, por lo que el garbage collector se convierte en el “delete” o “free()” de las 5.8 C++ aplicaciones basadas en JNIEasy evitando los consabidos JNIEasy también aporta herramientas para acceder a memory leaks de los que han estado plagadas las métodos C++ en DLLs, clases Java emulando clases aplicaciones C/C++. C++ cuyos métodos y atributos “normales” pueden ser Conseguimos en resumen una programación “nativa” visto como métodos y atributos “C++” etc. con Java, con filosofía Java y con mayor robustez y seguridad que usando un lenguaje nativo. 6 ¿Hacia un desktop “muy” Java?

El tiempo lo dirá, JNIEasy es un paso más en esa 5.7 Exportación de funciones dirección. Una de las características más interesantes es la capacidad de acceder directamente al método de una Referencias callback desde código nativo sin JNI y sin conocer la dirección de memoria previamente. Se mimetiza así la [1] JNIEasy. http://www.jnieasy.com exportación de un método de una DLL pero ¡desde Java!. [2] Microsoft domina el mercado de sistemas operativos, pese al éxito de Linux. Dealer World, 09/10/2003 Sea el código Java: http://www.idg.es/dealer/actualidad.asp?id=32481 [3] JDesktop Integration Components. public class CallbackTest { https://jdic.dev.java.net/ public static long suma(int a,int b) { [4] Java Media Framework. http://java.sun.com/products/java- return a + b; } media/jmf/ } [5] JNIWrapper. http://www.jniwrapper.com reflMethod = CallbackTest.class.getDeclaredMethod( "suma",new Class[]{int.class,int.class}); JNIEasyLibrary dll = JNIEasy.getInstance().getJNIEasyLib(); dll.exportMethod(reflMethod, CallConv.STD_CALL);

Sea el siguiente código C/C++:

HMODULE dllHandle = ::LoadLibrary("JNIEasy.dll"); void* (__stdcall *findCBAddress)( const char*); findCBAddress = (void* (__stdcall *)( const char*))::GetProcAddress(dllHandle, "_findExportedMethodAddress@4"); const char* sig = "CallbackTest.suma(int,int)";

64 Actas del II congreso javaHispano

Guasaj. Un framework de programación basado en componentes

Benito Mateo, Urko Blesa Jarque, Ángel Lop lis, José Javier Golf Enparantza, Nº 1, 3 A Plaza del Olmo, Nº 5, 2º Piso Isabel la Católica, Nº 16-18, Piso 5 C,Esc. Izq. C.P. 20.160 Lasarte (Gipuzkoa) C.P.44770 Escucha (Teruel) [email protected] [email protected] C.P. 50009 Zaragoza [email protected]

Abstract 1 Motivación. Origen de guasaj. En el ciclo de vida de un proyecto, independientemente del proceso de desarrollo que se utilice (RUP, FDD, XP, etc…) en El origen desde el cual guasaj fue concebido fue crear un un determinado momento se debe pasar del análisis de los entorno de trabajo en el cual se defina un procedimiento requisitos al diseño e implementación del mismo. para plasmar el análisis y diseño de la solución de un problema en un conjunto de componentes reutilizables. Los patrones de diseño hacen colaborar un conjunto de clases e instancias de las mismas, para solucionar un Con ello se pretende aumentar la productividad a través de problema determinado permitiendo obtener una solución con dos cuestiones: buenas características de acoplamiento, cohesión, • El establecimiento de un procedimiento claro de granularidad, rendimiento, adaptabilidad, evolución, etc. , pero implementación de las funciones descubiertas en el con los patrones de diseño sólo no basta, no dicen análisis y el diseño. directamente que modelo superior crear para hacer colaborar N paquetes de casos de uso, y que permanezcan • La reutilización automática del trabajo realizado en el desacoplados, independientes, reutilizables, etc.. paso anterior.

En la búsqueda de este modelo superior surge el componente En primer lugar se pretende crear un esquema de clases de software como unidad independiente, cooperativa, sencillo para la implementación de componentes, con un desacoplable, etc. ciclo de vida, en la llamada a sus servicios, lógico y que cumpla las premisas de los patrones de diseño Lo que pretendemos con este proyecto es proponer una sobradamente conocidos [1] (MVC, command, service metodología de organización de código en torno a locator, factory, etc…). A través del estudio de la filosofía de componentes con una estructura basada en patrones de creación de aplicaciones basadas en componentes pasar a diseño bien conocidos(MVC, Observer, ViewDispatcher, una implementación de la misma, sencilla, pero potente y Factory, Command, Facade, VO, Service Activator , Service flexible, creando una asociación rápida y semiautomática Locator, …) que nos lleve del análisis de los casos de uso entre el modelo conceptual de una aplicación y su (historias, requisitos funcionales, casos de aplicación, etc…) correspondiente implementación. a la implementación de la solución en código de una manera metódica, repetible y con resultados reutilizables en Con este proceso se pretende eliminar, dentro de lo posible, diferentes proyectos.. el problema de tener que “reinventar la rueda” en cada proceso de análisis y diseño de un determinado problema, Keywords: framework, patrón, componente, metodología. muchas veces supeditado a la imaginación e inspiración en el diseño final del arquitecto/diseñador/programador.

Otro de los factores o puntos de especial interés radica en el hecho de establecer una definición, implementación, manejo, capacidades, y ciclo de vida de los componentes, de tal manera que todo el equipo de desarrollo emplee el mismo idioma.

65 Actas del II congreso javaHispano

En definitiva, ir un paso más allá de los patrones de diseño modelo, una gestión clara de los datos del proceso, un en el establecimiento de un lenguaje común para la manejo de excepciones efectivo, y una posibilidad de nomenclatura de las funciones, comportamiento y reutilización practica y rápida, desde el principio, de la arquitectura de un sistema. codificación, de tal manera que la exportación de funcionalidades desde un proyecto a otro sea automática. 2 Problemas detectados en el desarrollo de programas en la actualidad 3 Del análisis a la programación. Pasos y trabas intermedias En la labor de desarrollo de proyectos software se presentan una serie de problemas con demasiada En cualquiera de las metodologías o procesos de desarrollo frecuencia, como son: de software, salvando sus peculiaridades, se sigue un proceso similar al que se describe a continuación para la • Dificultad en el paso de análisis, al diseño y consecución de la solución a un proyecto: codificación. La identificación y agrupación de las funcionalidades del sistema en paquetes y su posterior • Estudio de los requisitos. paso a codificación no está suficientemente • Análisis de la solución. Modelo conceptual. sistematizado. Descubrimiento de las entidades del problema. • Poca o ninguna aplicación de patrones de diseño para Agrupación en paquetes conceptuales. resolución de problemas genéricos en los proyectos • Diseño de la solución. Patrones. Establecimiento de la cotidianos, debido en parte a la dificultad para abstraer arquitectura. Diseño de pruebas. Cumplimiento de la problemática concreta de un gran proyecto, a las requisitos no funcionales, etc… soluciones a un nivel más micro que aportan los patrones de diseño. Se hace complicado pasar de • Codificación. Llegado este momento en determinadas pequeñas implementaciones de soluciones en una serie metodologías podemos estar en un estado más o menos de clases y objetos aplicando unos determinados avanzado en la identificación de clases y métodos a patrones, a la implementación de una serie de paquetes implementar, pero en general se dista bastante de tener o componentes que desarrollen una parte concreta, una visión clara y lo más importante, acertada y con independiente, reutilizable, extensible y configurable de posibilidades de ser la definitiva. Esto deriva en una la aplicación de un tamaño considerablemente mayor. lógica de negocio más o menos dispersa en métodos de clases cuyas responsabilidades no están claramente • No existe una separación clara entre la vista de la definidas. Esto puede llevar a gravísimos problemas de aplicación y el modelo, sucumbiendo en la mayoría de acoplamiento entre partes funcionales del sistema, las veces ante la dificultad de disociar las distintas difíciles de independizar a posteriori, siendo muy difícil porciones de código que participan en una parte de la cuando el modulo en cuestión tiene ya un tamaño solución, interface gráfico, eventos del GUI, validación considerable y nos percatamos de las limitaciones de datos, acceso a datos persistentes , etc … impuestas, pensar en una refactorización del diseño que • Dificultad de programación para el interface en lugar de no nos provoque más de un dolor de cabeza y desde la implementación. luego una merma en nuestra productividad.

• Mala gestión de la creación – instanciacion de objetos 3.1 Solución. Aplicación de patrones tanto para ejecutar la lógica del sistema, como para Los patrones nos aportan buenas prácticas de código, en la representar el estado del mismo en un momento dado. pequeña escala, para salvar de una manera óptima y muy • No se define una separación clara entre al estructura de probada circunstancias que se dan en la programación datos que almacenan el estado del sistema en cada cotidiana. momento de ejecución del mismo, y las diferentes El uso de patrones hace que las porciones de código operaciones que se pueden realizar sobre dichos datos. resultantes sean robustas, flexibles, extensibles, adaptables, No existe, en general, un procedimiento sistemático para optimizadas y fiables, de tal manera que el conjunto de la codificar la funcionalidad que se requieren (casos de uso, aplicación también herede dichas cualidades. Esto es lo que historias, requisitos arquitectónicos, características se pretende pero en el camino para lograrlo se tiene una funcionales y no funcionales, etc), de tal manera que mantengamos desde el principio un separación entre vista y

66 Actas del II congreso javaHispano

serie de imponderables, que hacen que las decisiones de • El cliente de un componente estará desacoplado del diseño no sean triviales. mismo, ni siquiera a través de una interface. La resolución del componente y del método a ejecutar se En el momento de diseñar la solución para una aplicación el realizará en tiempo de ejecución arquitecto/diseñador debe tener una concepción de las entidades y la colaboración entre las mismas que le harán • Los componentes que participan en una aplicación, la desempeñar la solución requerida, así como una capacidad descripción de los mismos en cuanto a comportamiento de abstracción para descubrir entre estas entidades la y aspectos (acceso, relaciones, vista, excepciones, log) problemática que encierran y que parte de ésta, está debe tener un soporte de configuración exterior al contemplada como patrón sobradamente conocido. código (archivo xml de configuración).

3.2 Problemática de los patrones en la • Los componentes deben permitir la ejecución codificación secuencial de dos métodos de distintos componentes, o desde uno de estos a otro. El hecho de que un método El uso de patrones de diseño en la solución de una de un componente sea llamado desde otro puede aplicación facilita el paso del diseño a la implementación por provocar en determinadas circunstancias que la estar estos ya codificados en multitud de ocasiones. Aún respuesta de éste sea de un tipo o de otra así, hay un nivel de abstracción intermedio en las soluciones genéricas que aportan los patrones, y los problemas de • Un componente tiene una lógica de negocio modelado, diseño, empaquetado, y reutilización de código representado por un BO (Bussiness Object) con los que se necesitan en los proyectos con una tamaño métodos operativos, y además un componente trabaja considerable, sobre todo en sistemas en los que se con un conjunto de datos en forma de VO (Value desarrollan una serie de aplicaciones (suite) para dar una Object). serie de servicios integrales a una empresa. • El estado en memoria de un componente en un La solución puede pasar por la elaboración de un determinado momento de ejecución (por ejemplo, un framework que encapsule las buenas prácticas de los servidor de Chat, con una serie habitaciones y unos patrones sobradamente conocidos y haga que los usuarios en las mismas, en un determinado momento) programadores sean capaces de representar el modelo se debe reflejar en este BO. Pero no una instancia del lógico de la solución del problema, expuesto en el análisis, BO por cada elemento a reflejar. Por ejemplo, el con un buen diseño, una buena arquitectura y un código componente “Habitación” en una aplicación de chat, ampliamente reutilizable sin tener que implementar estaría formado por un BO con las operaciones y una físicamente los patrones, sino que sea el framework el que lista de posibles habitaciones. maquille para el desarrollador final el uso de los mismos. • De esta manera un componente será gestor y almacén Dicho de otra manera, el hecho de programar bajo este de los datos que puede manejar. Los componentes son framework garantiza la herencia de la mayoría de los elementos de peso de tal manera que en el sistema no patrones de diseño más utilizados, sin prohibir en absoluto tendremos múltiples instancias de un componente[1], la implementación de alguno de los mismos para cubrir una sino que será el componente el que maneje los datos determinada necesidad. necesarios y trabaje con las operaciones para construir 4 Condiciones deseadas en la solución y manejar el estado del sistema en un momento dado.

Un framework que pretendiese implementar una solución • Cuando en una vista de un componente se lleve a cabo para la problemática anteriormente descrita deberá poseer un cambio, dicho cambio deberá ser reflejado de alguna una serie de características como: manera en el estado de la lógica del componente, en su BO, es decir, un cambio en una de las vistas se ve • Guiarse por un patrón de comportamiento como el MVC reflejado en su homónimo del modelo. Por ejemplo, para la separación de vista, modelo y controlador. cuando en un componente gestor de barra de • El código resultante debe quedar en forma de herramientas seleccionamos un elemento y desde otro componente reutilizables, y cumplir con el paradigma y componente, queremos acceder al elemento filosofía de construcción de aplicaciones basadas en seleccionado. No podemos desde una vista de un componentes tal y como se detalla más en profundidad componente acceder directamente a la vista de otro, en [2].

67 Actas del II congreso javaHispano

debemos pasar por el modelo y solicitar algún atributo incluso plataforma, si están diseñados para ello. Por que nos de la información que requerimos. ejemplo, un componente para comunicaciones TCP (cliente y servidor), un componente para selección y gestión del idioma para una aplicación, un componente manejador del 5 Características de los componentes estilo y fuentes de una aplicación, un componente guasaj calendario, un componente calculadora, etc…

Un componente guasaj es un conjunto de clases diseñadas De esta manera en la elaboración de una solución para llevar a cabo una serie de funciones relacionadas con completa para un problema, partiremos del modelo un problema del modelo de negocio del sistema o tradicional de resolución de problemas software, de la desarrollar una función de carácter más amplio dentro de la siguiente manera: arquitectura, estando este acompañado de un fichero de descripción de las características y posibilidades de • Se plantea una serie de requisitos o funcionalidades a ejecución de dicho componente. Ejemplo, roles de usuario, desarrollar. pre y post ejecuciones, controlador de excepciones, • Se lleva a cabo un análisis funcional y se determina un métodos virtuales… modelo conceptual en el que se descubren entidades, Un componente guasaj es autocontenido en su ciclo de vida, relaciones entre estas y atributos de las mismas. llevando a cabo una separación entre lógica de negocio y • Se realiza una agrupación en paquetes guiándose por datos, así como vista y modelo. En un principio la una determinada premisa pudiendo esta ser, plataforma objetivo de guasaj es la J2SE aunque su filosofía agrupación por función, agrupación por complejidad, es extrapolable tanto a J2EE como J2ME. Todo agrupación por arquitectura, agrupación por componente aporta un mecanismo de llamada a sus departamento lógico del cliente, etc, etc.. Suele ser en servicios, un método de gestión y acceso a sus datos, así este momento donde empiezan a surgir los problemas como un control de sus vistas, manejo de excepciones y separación de responsabilidades entre las entidades del control de acceso. sistema. Aquí evidentemente no hay magia que valga, Dentro de los tipos de componentes que podemos la decisión final de agrupación, separación de desarrollar se pueden encontrar 2 tipos principales con sus responsabilidades de cara a un diseño u otro es propia peculiaridades y variantes: del arquitecto /diseñador, siendo muchas veces equivalentes soluciones con topologías de entidades diferentes.

Componente entidad: Son componentes que intentan Una cuestión que puede y debería ayudar sobremanera en representar el modelo lógico de negocio propio de un este paso del proceso de desarrollo, sería el hecho de saber proyecto asumiendo una serie de características de la exactamente el procedimiento de codificación que solución final. Estos componentes desarrollan una función, seguiremos para llegar a implementar esta entidad, e tienen una responsabilidad y unos mecanismos o reglas de igualmente los servicios a los que tendremos acceso sólo interacción con otros componentes de entidad o de servicio. por el hecho de implementar la entidad de acorde a este Un ejemplo de componente representativo de una entidad procedimiento / framework de programación. del modelo de negocio podría ser los componentes cliente, factura, proveedor, empresa, albarán, etc... por ejemplo, en La idea radica en crear una equivalencia entre cada uno de una aplicación de gestión. En un sistema de tratamiento de los términos utilizados en el análisis funcional de la señales provenientes de un sistema de instrumentación aplicación y la codificación de los mismos. Saber medir que electrónica, estos pudieran ser, equipo, señal, punto de implicaciones tendrá el hecho de utilizar palabras como medida, etc. En general los candidatos a este tipo de paquete, clase, entidad, atributo, relación, caso de uso, componentes pueden ser los provenientes del análisis servicio, etc.… en la codificación del sistema. conceptual del dominio del problema. 6 Introduciéndonos en guasaj Componentes genéricos de servicio: Componentes que De esta manera y según lo expuesto fundamentos de los permanecen completamente independientes de las cuales parte el desarrollo de guasaj son: peculiaridades de un determinado proyecto siendo totalmente reutilizables en otro ámbito de ejecución e • Separación en modelo, vista y controlador.

68 Actas del II congreso javaHispano

• Independencia de componentes. • Primero, indicar si queremos manejar vista o no.

• Variación del comportamiento de un componente según • Segundo, indicar que método de que componente una definición exterior, sin modificar el código. queremos que maneje la respuesta en forma de vista.

• Estandarizar la nomenclatura y tipo de clases al crear • Tercero y último, si para ese componente queremos un componente reutilizable. instanciar una nueva vista o manejar una que pasamos en la llamada al método. Tres en uno. • Crear un elemento amigable tanto para el analista como para el programador del sistema, pasando por el Así, teniendo la ventaja de una separación entre arquitecto y el diseñador. componentes, podemos acceder a través de las funciones del contenedor (éste las resuelve en tiempo de ejecución, 6.1 Localización de componentes por no de desarrollo), a otros componentes para pasarles nombre. (notificarles) resultados de operaciones de otros Para tener acceso a los servicios de un componente componentes. Esto corresponde con la teoría de inversión debemos primero localizar una instancia de dicho de control [3], por la cual es el contenedor el que llama a componente. Para ello, pasaremos un nombre único con el nuestras clases para realizar ciertas funcionalidades en un que denominaremos unívocamente a un componente dentro momento dado. de la aplicación y estará referido en el fichero de descripción guasaj y del componente. 6.4 Posibilidad de llamar a métodos no bloqueantes. Una vez localizado un componente y apuntado por una Sin tener que esperar a que termine la ejecución del método interfaz común para todos podremos llamar a los servicios llamado. Esta utilidad resulta interesante cuando queremos que implementa. tener un mecanismo automático de ejecución en segundo 6.2 Ejecución de métodos de los plano de una operación y recibir la respuesta de esta componentes dinámicamente. cuando finalice la misma, sin que tengamos por ello bloqueado el flujo principal del programa, esperando Resolución de los métodos a ejecutar según la firma del retornar de la llamada efectuada. Un ejemplo concreto de método, nombre y paso de parámetros, pudiendo derivar en esta funcionalidad seria la localización remota de un servicio diferentes comportamientos en la ejecución y la respuesta o componente que puede llevar unos segundos. Es posible según los parámetros pasados. que no podamos seguir la ejecución de algo concreto sin 6.3 Posibilidades de redirección a la vista. este componente o servicio pero eso no impide que podamos ejecutar otras opciones del programa y ser Cuando se llama a un método de un componente, se quiere avisados cuando se haya localizado el componente o llevar a cabo una funcionalidad y generalmente obtener un cuando haya vencido el plazo de timeout. resultado de la misma, acompañada de una visualización de los resultados. Otras veces, se quiere ejecutar la lógica de 6.5 Concentración del manejo de modelo pero no se quiere visualizar el resultado de la misma excepciones. a nivel de interface gráfico, sino que sólo se quiere manejar A través de un HandlerException por componente. los datos del resultado de la operación. De esta manera se Mecanismo por el cual las excepciones producidas son puede elegir en el momento de la llamada a un método de dirigidas a un método de una clase que se ocupa de su un componente si queremos ejecutar la parte de vista gestión y tratamiento. También existe la posibilidad de vinculada a ese método o no. Igualmente, podemos indicar definir si el trato de excepciones se procesa en el en el momento de la llamada qué método y de qué componente original o si se redirecciona a otro manejador componente queremos que se haga cargo de manejar la en el proyecto destino (ya que dependiendo de cómo y respuesta en forma de vista de ese método. Y aún hay más, dónde se ejecute un componente puede que no queramos podemos decirle en que instancia de dicha vista queremos ni deseemos su tratamiento original o incluso necesitemos que se ejecute el método de respuesta, en el caso de que capturar las excepciones producidas por un componente y manejemos diversas instancias de vista de la misma clase. tratarlas a nuestro modo). Con todo lo anteriormente expuesto, tenemos tres funciones relacionadas con la vista:

69 Actas del II congreso javaHispano

6.6 Control de acceso a los métodos y original, puede modificar los mismos, y llamará al método componentes por rol de usuario. original con éstos. Un ejemplo de preejecución, puede ser A través del fichero de descripción del componente se incluir un sistema de logs a un determinado método. En el puede indicar que roles de usuario tendrán acceso a cada caso de la postejecución, un posible ejemplo sería la método. Lo único que se debe realizar es activar en el elaboración de un informe al término de la ejecución de un contenedor guasaj el rol de usuario activo. En tiempo de método, necesitando para ello, los parámetros de entrada, ejecución comparará si el rol activo coincide con alguno de respuesta del método original y los posibles cambios que los que tiene permiso de ejecución. El proceso común será haya podido originar dicha llamada, como escritura en base aprovechar el momento en el que pidamos validación al de datos, cambios de estado, alteración de ficheros o usuario para recoger de este el rol de usuario y activarlo en configuraciones, etc… guasaj. Para este usuario cuando ejecute el resto de Y por último, un ejemplo de intercepción sería el hecho de operaciones su nivel de acceso vendrá determinado por dotar de un sistema de cifrado a un mensaje pasado entre dicho rol. componentes. Podríamos capturar los datos de la llamada original, cifrarlos o descifrarlos y continuar con la llamada en 6.7 Métodos virtuales. el componente destino que se ejecutaría ya con los datos Son métodos que no está implementados en el componente cifrados o descifrados. original, sino que estarán redireccionados a otro método de Los métodos, pre, post e interceptor son ejemplos claros de otro componente que será el que realmente se ejecute, componentes que dotan una funcionalidad añadida no recibiendo los parámetros originales. Esta función es contemplada anteriormente en el sistema. necesaria para permitir que las llamadas a métodos realizadas desde el “interior” del componente puedan ser 7 Otras consideraciones en los capturadas y manejadas por otro componente. Por ejemplo, componentes guasaj tenemos un componente que gestiona conexiones TCP, atiende a los clientes conectados, y recibe peticiones de los Los componentes guasaj están concebidos desde un mismos. Este componente es reutilizable en multitud de principio con una vocación de reutilización de los mismos en proyectos, pero no sabemos en tiempo de implementación diferentes ámbitos y soluciones informáticas, sin por ello del componente que método de que clase tenemos que acarrear un malus de productividad para el usuario final de llamar cuando recibamos una trama, ya que, los mismos como desarrollador de aplicaciones guasaj. Al evidentemente, dependerá de lo que queramos hacer con la contrario al pensar directamente en la reutilización del misma en el proyecto que nos ocupe. Para ello podemos trabajo realizado se tienen en cuenta desde las fases más definir un método virtual en este componente, receiveData, tempranas de codificación unas características de que será invocado por cada hilo gestor de un cliente arquitectura y diseño muy positivas. La clave de todo este conectado, para indicar que nos ha llegado una trama de proceso resulta en no crear una abstracción vacía de datos. En el fichero de descripción de componente elementos software de difícil implementación sino todo lo indicaremos que éste método es virtual y qué método de contrario, dotar de un framework que nos haga una gran qué componente queremos que se ejecute cada vez que se parte del trabajo de nomenclatura de nuestras clases, llame a dicho método virtual. separación de responsabilidades, posibilidades de relación entre componentes y acceso a los servicios de los mismos 6.8 Preejecución, postejecución e desde cualquier parte de la aplicación. intercepción de métodos. 8 Conclusiones En la descripción de un método, dentro del archivo de configuración del componente, podemos especificarle un En la ejecución de un proyecto software, el paso del análisis método que se ejecutará antes que este. Este último recibirá del problema al diseño y codificación presenta una serie de los parámetros del método original para su ejecución. En el dificultades para asignar las diferentes responsabilidades caso de queramos una postejecución, podemos definir un entre las unidades de código que vamos creando. Dentro de método que se ejecutará con posterioridad a la ejecución las unidades de código queremos mantener una separación del método original. En este caso este método recibirá tanto entre la lógica de negocio y la vista. Gran parte del código los parámetros del método original como la respuesta que generamos para la solución de un determinado producida por este. Y por último, en el caso de la problema deberíamos poder reutilizarlo en parte o por intercepción, el método interceptor recibe los parámetros del completo, con alguna pequeña variación de configuración

70 Actas del II congreso javaHispano en otros proyectos, dentro del mismo ámbito o no. El componente guasaj nos permite crear estructuras de código que desarrollen un conjunto de funciones reutilizables en otros proyectos. Los patrones de diseño por si mismos no establecen un lenguaje suficiente para la nomenclatura de la funcionalidad, comportamiento y arquitectura de un sistema. Debemos ir hacia una entidad de mayor calibre que cubra esta necesidad.

Resulta fundamental definir un conjunto, framework - procedimiento, que automatice el proceso de codificación del sistema, sin depender en exceso de la inspiración particular, para llegar a lograr un diseño arquitectónico correcto, repetible y reusable, todo ello en aras de una mayor productividad y calidad software.

Agradecimientos

Queremos agradecer a la EUPLA la posibilidad de contribuir a este congreso con el desarrollo de este trabajo. Igualmente a ARCO ELECTRÓNICA S.A, las facilidades para la realización del mismo, y la asistencia a este congreso. También un agradecimiento especial para Sergio Gil García por contribuir en los inicios de esta idea.

Y en especial a la comunidad javaHispano por permitirnos participar en este congreso.

Referencias [1] Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides. Design Patterns. Element of Reusable Object- Oriented Software, Addison-Wesley, 1995. [2] Claudia Patricia García Zamora y Samuel Garrido. Programación basada en componentes. CINVESTAV México D.F 4 - Noviembre -2003. [3] Mike Spille, Inversion of control http://www.pyrasun.com/mike/mt/archives/2004/11/06/15.46.14 /index.html

71 Actas del II congreso javaHispano

72 Actas del II congreso javaHispano

Extensión del patrón Observador para la integración de eventos de componentes heterogéneos.

Luis Rodero Merino Miguel A. Ortuño Pérez Luis López Fernández Univ Rey Juan Carlos, DIET Univ Rey Juan Carlos, DIET Univ Rey Juan Carlos, DIET [email protected] [email protected] [email protected]

Abstract 2 El patrón Observador

En este artículo presentamos una extensión al ya conocido El patrón Observador es uno de los 23 patrones patrón Observador. Esta extensión está orientada a descritos en [2]. Este patrón “Defines a relationship facilitar la monitorización de eventos provenientes de between a group of objects such that whenever one distintos componentes de un sistema. Este artículo también object is updated all others are notified automatically”. contiene un ejemplo de como aplicar este patrón dentro El objeto observado no necesita saber nada acerca de los del contenedor PicoContainer. observadores. Son los observadores quienes deben registrarse como 'oyentes' para poder recibir eventos. Palabras clave: Observador, observable, patrón, contenedor, componente. Esto permite el desarrollo de aplicaciones con componentes poco acoplados. el bajo acoplamiento se considera una ventaja ya que simplifica la posterior 1. Introducción reutilización de componentes.

El patrón Observador es uno de los más ampliamente Los oyentes reciben notificación de todos los eventos utilizados en la programación de sistemas, aunque a generados en los objetos observados. Pueden registrarse veces incluso el programador no sabe que lo está en cualquier momento durante el ciclo de vida del usando. Hay dos roles básicos en este patrón: el componente. componente observable, que lanza eventos para Este patrón debe aplicarse cuando: notificar cambios en su estado, y el observador que espera y recibe esos eventos. • Cambios en algunos de los objetos del sistema requieren cambios en otros objetos del mismo grupo. El API estándar de Java [3] contiene la interfaz • El número de oyentes puede variar durante el ciclo de java.util.Observer y la clase abstracta vida del objeto. java.util.Observable, que pueden ser usadas como base • El bajo acoplamiento es un requerimiento básico del para la implementación de este patrón. Aunque como diseño.. veremos más adelante, esta solución es muy limitada Este patrón implica dos roles distintos, como se muestra cuando se necesita manejar notificaciones desde en la Figura 1. distintos componentes dentro del mismo sistema, cada uno capaz de generar sus propios eventos. El patrón es bastante sencillo, y puede encontrarse como parte de otros patrones más complejos tales como el Este artículo muestra una extensión del patrón patrón Modelo Vista Controlador, donde el controlador Observador que simplifica el manejo de distintas fuentes es un observador que recibe eventos de la interfaz, y la de eventos dentro de un sistema. El artículo comienza vista recibe eventos referidos a cambios en el modelo. con una definición más completa y profunda del patrón Observador, y describe sus limitaciones, mostrando las dificultades que pueden surgir al usarlo. Después se explica la extensión que hemos desarrollado, comentando sus ventajas y cómo aplicarla. Finalmente mostramos un posible uso de esta extensión aplicándolo dentro del contenedor de componentes PicoContainer.

73 Actas del II congreso javaHispano

El Gestor de Cambios puede ser un gestor sencillo, que sólo reenvíe eventos desde cualquier objeto observable a todos los observadores. Pero también puede ser más complejo, guardando información acerca de qué eventos interesan a qué observadores. En ese caso, el Gestor reenviaría a cada oyente sólo los eventos por los que está interesado.

Esta solución, aunque más potente, también presenta problemas:

• Los oyentes aún necesitan saber los componentes que deben observar, aunque es posible que sólo sepan los eventos que quieren recibir. Si el oyente es un componente externo al sistema, entonces es posible que Figura 1 Patrón Observador no sepa cuales son esos componentes. • En algunos casos, puede que no todos los observadores deban ser informados acerca de todos los eventos que ocurren en el sistema, incluso aunque estén interesados en ellos, por razones de seguridad o rendimiento. 3 Desventajas del patrón Observador • Si los observadores tardan un tiempo apreciable en Debido a su sencillez, el patrón Observador tiene procesar eventos, el rendimiento del sistema puede verse afectado. Este hecho se agrava si los componentes son algunas desventajas: externos al sistema. • Todos los oyentes reciben todos los eventos lanzados, sin • Si se generan muchos eventos, el tiempo para crearlos y distinción. Esto es ineficiente, y los observadores reenviarlos puede ser no despreciable. Esta circunstancia deberían ser capaces de registrarse sólo para aquellos se agrava cuando se utiliza un estrategia push para la eventos en los que estén interesados. transmisión de la información referida al evento. Esto significa que el evento transporta toda esta información, A menudo los sistemas tienen varios componentes que • por ejemplo el nuevo estado del componente observado. son generadores de eventos, y varios componentes que Para solucionar este problema debería ser posible fijar escuchan por esos eventos. Las relaciones entre todos los eventos que deben ser creados y los que deben ser estos componentes pueden ser difíciles de maneja. Ver ignorados. por ejemplo la Figura 2 • La implementación de políticas referidas al manejo de eventos no es una tarea trivial, ya que puede implicar el trabajar con componentes y oyentes repartidos a través de todo el sistema. • Java no implementa herencia múltiple. Por lo tanto, muchas clases no serán capaces de heredar de java.util.Observable ya que ya tienen otra clase padre.

Para concluir, hay otro problema que aparece en un ámbito bastante más concreto. Si se usa un contenedor de componentes para hospedar las partes del sistema es bastante probable que algunos componentes deseen ser avisados acerca de eventos relacionados con el ciclo de vida de otros eventos. Esto es, cuando son creados, iniciados, parados... Sin embargo, no es posible asegurar que todos los componentes mandarán los eventos Figura 2 Varios componentes observados y observadores apropiados (puede que sean componentes 'importados' al sistema y desarrollados por otros). Además, puede discutirse si es el componente y no el contenedor quien Gamma et al. [2] ya sugerían utilizar un mediador debe generar estos eventos. (patrón Mediador [2]), llamado Gestor de Cambios. El mediador mantiene las relaciones entre oyentes y 4 Administrador de Eventos, Anunciantes componentes observados (Figura 3). Los problemas descritos en la sección anterior fueron detectados durante el desarrollo de un sistema peer to

74 Actas del II congreso javaHispano

peer. Un requisito importante es que debíamos ser Administrador de Eventos). Si es así, la instancia del capaces de monitorizar y registrar todo lo que ocurriera evento correspondiente es creada y enviada al en el nodo (eventos referidos a conexiones, Administrador de Eventos. Este notificará el evento a los búsquedas...). Nos enfrentamos al problema de observadores monitorizar todos estos eventos, y concluimos que lo Este mecanismo tiene las siguientes ventajas:

• Los componentes no necesitan heredar de la clase java.util.Observable. • Los eventos que no pasen el filtro no son instanciados, mejorando por lo tanto el rendimiento.. • La administración de políticas está centralizada en un punto.

En la Figura 4 vemos como los anunciantes se sitúan entre el Administrador de Eventos y los componentes

4.3 Administración de eventos centralizada Figura 3 Gestor de Cambios El uso de un Administrador de Eventos y un Anunciante mejor era utilizar un sistema de gestión de eventos permite usar una implementación centralizada de la centralizado. Más adelante añadimos nuevas gestión de eventos. Los programadores pueden capacidades al nodo, por ejemplo la posibilidad de fijar centrarse en la lógica de los componentes, ya que la filtros de eventos. creación y reenvío de eventos son manejados por el Anunciante correspondiente. Además, la administración Para todo ello, hemos desarrollado una extensión del de eventos es facilitada ya que las tareas relacionadas patrón Observador, introduciendo Anunciantes y un con los eventos se realizan en un único punto. Así, la nuevo Administrador de Eventos que sustituye al Gestor especificación de políticas referidas a notificaciones de Cambios. (filtros, permisos...) puede hacerse llamando a los métodos adecuados del Administrador de Eventos. Sin 4.1 Administrador de Eventos este, la implementación de políticas es una tarea El Administrador de Eventos sigue la misma idea que el complicada que implica trabajar con todos los Gestor de Cambios explicado en la sección 3. Se sitúa componentes observables. entre oyentes y componentes observables, y mantiene Un Administrador de Eventos, o un componente similar, las relaciones entre estos. Pero también añade algunas podría estar presente dentro de un contenedor de capacidades nuevas: componentes. Así, el manejo centralizado de eventos • Un observador puede registrarse para recibir cualquier sería un servicio más proporcionado por dicho evento, sin especificar el componente que lo genera. Esto es, la administración se centra en eventos y no en contenedor. El contenedor a su vez podría también crear componentes. notificaciones referidas a instantes del ciclo de vida de • Pueden especificarse filtros de eventos. Si algún evento los componentes. no pasa esos filtros, no es reenviado a los observadores. • El Administrador de Eventos contiene una cola de eventos que puede ser activada al inicio. Los eventos son almacenados en la cola, y un hilo dedicado se encarga de reenviar los eventos de la cola a los oyentes.

4.2 Anunciantes

Un anunciante es un objeto asociado al componente observable. El componente llamará su Anunciante siempre que un nuevo evento deba ser notificado. El Anunciante comprueba primero que el evento puede ser reenviado, es decir, pasa los filtros (usa una llamada al

75 Actas del II congreso javaHispano

Por ejemplo, Avalon [1] es un plataforma para la programación de componentes y contenedores. Uno de sus proyectos hijo es el contenedor Merlin, que proporciona varios servicios como los mencionados antes. Otros contenedores tales como Spring [4], , NanoContainer [5]... están también disponibles para la programación con componentes.

Figura 4 Administrador de Eventos, Anunciantes

5 Administrador de Eventos en el contenedor PicoContainer

En sistemas complejos, con un número grande de componentes, es fácil encontrar muchas fuentes posibles de eventos, así como observadores. Como se explicó en la sección anterior, el manejo de las relaciones entre observados y observadores y la implementación de políticas referidas al reenvío de eventos son tareas Figura 5 Diagrama de clases del Administrador de difíciles. Eventos y de los Anunciantes

Sin embargo, utilizar eventos para la comunicación entre Sin embargo, no hemos podido encontrar ningún componentes es una buena opción cuando se contenedor que proporcione un servicio de manejo de desarrollan componentes con bajo acoplamiento. eventos como el descrito en la sección 4.3. Además, nuestra experiencia demuestra que es mucho mejor y más factible utilizar eventos cuando se necesita Por ello, hemos tomado el contenedor PicoContainer [6] monitorizar el sistema desde un componente externo. e intentado añadirle capacidades para la gestión de eventos. Las razones por las que hemos elegido este En los últimos años nuevos contenedores han aparecido contenedor son básicamente dos: dentro del mundo Java. Aunque diferentes en • Es código de fuente abierta, que puede ser leído y complejidad y capacidades, comparten el mismo modificado. objetivo básico de facilitar el desarrollo de sistemas • Es un contenedor sencillo. Sólo resuelve dependencias mediante componentes. Las tareas básicas que suelen entre componentes, y no proporciona ningún servicio realizar son: extra. Esta simplicidad facilitó la comprensión y posterior modificación de su código • Instanciación y ensamblaje de componentes. El patrón Inversión de Control es usado normalmente para esta 5.1 Cambios realizados en PicoContainer tarea. Las dependencias entre componentes son automáticamente resueltas por el contenedor. Hay dos cambios básicos que hemos realizado sobre el • Mantenimiento del ciclo de vida de los componentes. contenedor. • Proporcionar servicios tales como logging, configuración... Primero ,un Administrador de Eventos ha sido añadido. Otras entidades puede acceder al mismo para fijar • Servicios avanzados tales como pools de threads, fuentes de datos... políticas de filtrado, para registrarse como observador, etc.

76 Actas del II congreso javaHispano

Segundo, a todos los componentes se les asigna un Anunciante que envía eventos referidos al ciclo de vida package jhii; del componente. Esto es, notifica cuando el componente public class PicoDefaultAdviser extends AdviserDefaultImpl es iniciado, parado. Este Anunciante no es llamado por implements PicoComponentAdviser { el componente, sino por el mismo contenedor, que es el public void componentStarted(){ que controla el ciclo de vida. Así el componente no if(component != null) necesita heredar de ninguna clase, ni implementar advise(new ComponentStartedEvent(component)); ninguna interfaz o llamar a ciertos métodos. No es else necesario cambiar el componente en absoluto, todo es advise(new ComponentStartedEvent(this)); hecho automáticamente por el contenedor. Sin embargo } es posible que el componente quiera proporcionar su propio Anunciante al contenedor, en el caso que tenga public void componentStopped(){ su propia implementación. Por supuesto, cualquier if(component != null) componente puede tener varios Anunciantes. advise(new ComponentStoppedEvent(component)); else Para conseguir esto, hemos extendido la clase DefaultPicoContainer para crear la nueva clase advise(new ComponentStoppedEvent(this)); PicoEventAbleContainer. Esta nueva clase mantiene las } relaciones entre componentes y Anunciantes. Los public void componentDisposed(){ Anunciantes manejados por este contenedor deben if(component != null) implementar la interfaz PicoComponentAdviser, tal y advise(new ComponentDisposedEvent(component)); como se define en la Figura 6. else package jhii; advise(new ComponentDisposedEvent(this)); public interface PicoComponentAdviser extends Adviser { } public void componentStarted(); } public void componentStopped(); Figura 7 PicoDefaultAdviser interface public void componentDisposed(); } Figura 6 PicoComponentAdviser interface

Cuando se instancia cualquier componente, si el componente implementa la interfaz PicoAdviserOwner Referencias significa que posee su propio Anunciante capaz de notificar eventos acerca de su ciclo de vida.. Así, el [1] Apache Avalon framework. http://avalon.apache.org contenedor utilizará este anunciante para notificaciones. [2] E Gamma, R. Helm, R. Johnson, J. Vissides. Design Patterns Si no, el contenedor crea una instancia del Anunciante Addison-Wesley, 1995. ISBN: 0201633612 por defecto PicoDefaultAdviser (ver Figura 7) y lo asigna [3] JavaTM 2 Platform, Standard Edition, v 1.4.2, API al componente. Specification http://java.sun.com/j2se/1.4.2/docs/api/

Después de cada paso en el ciclo de vida del [4] Java/J2EE Spring framework http://www.springframework.org componente el contenedor utiliza el Anunciante de ese componente y llama al método correspondiente, que [5] NanoContainer http://nanocontainer.codehaus.org creará un evento y lo mandará al Administrador de [6] PicoContainer http://picontainer.codehaus.org. Eventos para que sea reenviado a los oyentes. [7] Trygve Reenskaug, The original MVC. http://heim.ifi.uio.no/~trygver/themes/mvc/mvc- index.html.

77 Actas del II congreso javaHispano

78 Actas del II congreso javaHispano

Seguridad no intrusiva con Acegi Security System for Spring

Carlos Sánchez González Softgal Plgno. POCOMACO, parcela I, nave 19, 15190 A Coruña - España [email protected]

proporcionada por Acegi es mucho mayor, y además Abstract permite la integración con JAAS, utilizándolo en la fase

Uno de los aspectos que toda aplicación debe considerar es de autenticación. la seguridad, entendiendo como tal la necesidad de saber Acegi Security System [1] es un framework creado por que el usuario es quien dice ser (autenticación), y permitirle Ben Alex e íntimamente ligado al proyecto Spring [2], si acceso sólo a aquellos recursos necesarios (autorización). bien no requiere su utilización en nuestra aplicación, que Acegi Security System for Spring proporciona la facilita la tarea de adoptar medidas de seguridad en funcionalidad necesaria para adoptar mecanismos de aplicaciones Java, sean aplicaciones standalone o seguridad en aplicaciones Java utilizando características de aplicaciones web. Y lo mejor de todo es que es open programación orientada a aspectos, de forma transparente source, sin coste de licencias y con la seguridad añadida para el desarrollador, sin necesidad de desarrollar código, que proporciona el respaldo de un enorme y creciente utilizando para ello el soporte prestado por el framework grupo de usuarios que lo están utilizando, y con un Spring, pero siendo posible utilizarlo en aplicaciones no manual de referencia con más de 50 páginas que no desarrolladas con Spring. En este artículo se detallarán las tiene nada que envidiar a la documentación de un funcionalidades que ofrece y una visión detallada sobre la producto comercial. arquitectura del sistema, así como un simple ejemplo que demostrará la sencillez con la que se puede adoptar su uso. La arquitectura de Acegi está fuertemente basada en interfaces y en patrones de diseño, proporcionando las Keywords: Acegi, Spring Framework, seguridad, implementaciones más comúnmente utilizadas y autenticación, autorización, java. numerosos puntos de extensión donde nuevas funcionalidades pueden ser añadidas. Esta arquitectura puede hacer un poco difícil seguir el flujo de ejecución al 1 Introducción principio, pero una vez comprendida la idea global se Aplicar una política de seguridad a una aplicación es un acepta como el precio necesario para poder disfrutar de aspecto que afecta a prácticamente la totalidad de las un framework con una gran potencia. aplicaciones empresariales, y si no se adopta desde una Como ejemplo se mostrará la configuración realizada en perspectiva correcta puede llegar a ser una carga que el proyecto ONess [3] para la protección de peticiones afectará y lastrará el desarrollo del sistema. http en una aplicación web, además de mencionar uno Si bien existe el estándar JAAS (Java Authorization and de los completos ejemplos que se distribuyen con el Authentication Service) que pretende cubrir tanto proyecto. autenticación como autorización, su adopción dista mucho de ser sencilla y portable, debido a que el soporte 1 Autenticación proporcionado por los contenedores de aplicaciones dista mucho de ser adecuado, existen incompatibilidades Antes de poder tomar decisiones sobre si un usuario entre distintas implementaciones y cada contenedor puede acceder o no a un recurso, el usuario debe requiere una configuración distinta, normalmente con identificarse para comprobar su identidad. Para ello adición de librerías. Por otro lado la funcionalidad

79 Actas del II congreso javaHispano

existe el interfaz Authentication, desde el que se puede El proveedor DaoAuthenticationProvider merece una acceder a tres objetos: mención especial. Esta implementación delega a su vez en un objeto de tipo AuthenticationDao, un interfaz que • principal, típicamente un nombre de usuario. define un objeto de acceso a datos con un único método • credentials, las credenciales del usuario que loadUserByUsername que permite obtener la prueban que es quien dice ser, normalmente su información de un usuario a partir de su nombre de contraseña, aunque podría ser otro tipo de usuario. Acegi proporciona dos implementaciones de información como certificados electrónicos. este interfaz, InMemoryDaoImpl, en la que la información de los usuarios se guarda en memoria, útil • authorities, un lista de los roles que posee el para la realización de pruebas, y JdbcDaoImpl, que usuario o grupos a los que pertenece. accede a una base de datos a través de JDBC. Realizar Cuando el usuario se autentica se crea un objeto implementaciones de este interfaz es sumamente sencillo Authentication, con los dos primeros objetos, principal y y en el proyecto ONess [3] se encuentra disponible una credenciales. En el caso de autenticación mediante implementación que utiliza el mapeador objeto- nombre de usuario y contraseña se creará un objeto relacional Hibernate. UsernamePasswordAuthenticationToken. Entre otras características que también se proporcionan Acegi proporciona las clases necesarias para que esta de forma transparente, tan sólo estableciendo unos autenticación se realice mediante usuario y contraseña, parámetros de configuración, son soporte para cifrado utilizando un adaptador para enlazar con la de contraseñas (SHA y MD5), caché de la información de autenticación proporcionada por un contenedor de autenticación y redirección automática de peticiones aplicaciones como son catalina, jboss, resin o jetty, o http a canales seguros https para aquellas urls que utilizando el servicio de Single Sign On que proporciona deseemos. el proyecto CAS de la universidad de Yale [4]. Para el caso de aplicaciones web existen tres formas de Una vez creado este objeto Authentication se pasa al que un usuario se autentique: AuthenticationManager, que a partir del principal y las • Utilizando autenticación de tipo BASIC, definida credenciales determina si éstas concuerdan con las en el RFC 1945, el usuario introduce su usuario esperadas, añadiéndole al objeto Authentication las y contraseña en una simple ventana emergente authorities correspondientes en caso afirmativo o del navegador. Es necesario en el caso de que se lanzando una excepción de tipo AuthenticationException quieran añadir características de seguridad a en caso contrario. servicios web. Acegi proporciona una implementación del gestor de • Autenticándose mediante un formulario web, es autenticación AuthenticationManager que debería ser la forma más habitual ya que permite integrar el suficiente para la mayoría de los casos, el formulario de login en la aplicación web. ProviderManager. Esta clase tan sólo delega la autenticación en una lista de proveedores configurable, • Utilizando el servicio de autenticación central cada uno de los cuales implementa el interfaz CAS de la Universidad de Yale [4], en caso de AuthenticationProvider. Entre las implementaciones de que se requieran características de Single Sign proveedores suministradas con el proyecto se On, de forma que el usuario sólo tiene que encuentran las necesarias para realizar la autenticación autenticarse una vez para todos los servicios contra varios servidores de aplicaciones (catalina, jboss, que puedan proporcionarse en el ámbito de una resin y jetty), contra un fichero de configuración JAAS, empresa, incluso en distintos servidores y contra CAS (la solución Single Sign On de la universidad desarrollados con distintos lenguajes de de Yale [4]), y contra un objeto de acceso a datos programación. usando DaoAuthenticationProvider, que es el Cada una de las formas anteriores requiere de la comúnmente usado puesto que es el que permite configuración del filtro correspondiente en el descriptor acceder a la información almacenada en una base de de aplicación web, BasicProcessingFilter, datos. AuthenticationProcessingFilter o CasProcessingFilter respectivamente. La forma de configurarlos es definir los

80 Actas del II congreso javaHispano

filtros como del tipo FilterToBeanProxy, delegando, • RoleVoter, que comprueba que el usuario según un parámetro de inicialización, en uno de los presente un determinado rol, comprobando si filtros anteriores definidos en el contexto de aplicación se encuentra entre sus authorities. de Spring, lugar donde pueden ser más fácilmente • BasicAclEntryVoter, que a su vez delega en una configurados. jerarquía de objetos que permite comprobar si Los clientes llamados “ricos” o aplicaciones standalone el usuario supera las reglas establecidas como también están soportados, utilizando un gestor de listas de control de acceso. autenticación remoto cuya implementación utiliza un El primer caso es el más común, proporcionando una servicio web en el lado del servidor, utilizando autenticación basada en grupos o roles, donde se RemoteAuthenticationManager y permite el acceso si el usuario pertenece a alguno de los RemoteAuthenticationProvider. configurados como requeridos. En el segundo caso se permite restringir el acceso a objetos a nivel de instancia, 2 Autorización caso que será discutido más adelante.

Una vez el usuario está autenticado entra en juego la En ambos casos el sistema que intercepta las llamadas parte del sistema encargada de la autorización, con el fin debe ser configurado. En el caso de las aplicaciones web de permitir que el usuario acceda sólo a aquellos se hará mediante la configuración de un filtro en el recursos a los que tiene permiso. Para ello Acegi fichero web.xml. intercepta las llamadas a los objetos, utilizando proxies dinámicos u orientación a aspectos basada en AspectJ, o Los posibles recursos que se pueden proteger son las peticiones http, utilizando filtros, y actúa en • urls, mediante un filtro en el descriptor de consecuencia. Así permite restringir tanto llamadas a aplicación web, FilterSecurityInterceptor. métodos de determinadas clases o instancias, así como acceso a urls. • métodos de objetos definidos en el contexto de aplicación de Spring, utilizando Cuando se intercepta una petición a un recurso MethodSecurityInterceptor. protegido se comienza una cadena de eventos que finalizará permitiendo el acceso al recurso o lanzando • cualquier PointCut definible en AspectJ, una excepción AccessDeniedException. La cadena mediante AspectJSecurityInterceptor. comienza en un objeto de tipo AccessDecisionManager, que a partir del objeto Authentication y de los 2 Autorización a nivel de instancia parámetros de configuración decide si la llamada debe mediante listas de control de acceso proseguir. Acegi proporciona tres implementaciones de Existen casos en los que la protección de las llamadas a AccessDecisionManager que se basan en el concepto de métodos no es suficiente, necesitando protegerse de una votación, pero diferenciando las reglas de decisión: distinta forma distintas instancias de una clase. Como • UnanimousBased: permite el acceso si no hay ejemplo se puede pensar en un sistema de ficheros, en votos negativos los que cada archivo tiene distintos permisos, según si el usuario que accede a ellos es el dueño del archivo, • AffirmativeBased: permite el acceso si un voto pertenece al grupo del dueño o no cumple ninguna de es afirmativo las opciones anteriores. • ConsensusBased: permite el acceso si el número Acegi proporciona en sus últimas versiones el soporte de votos positivos es mayor o igual que el de necesario para implementar seguridad basada en listas negativos de control de acceso. Las clases clave que se deben Al igual que en la autenticación el ProviderManager conocer son delegaba en una lista de AuthenticationProviders, en el • BasicAclEntryVoter obtiene las ACLs del objeto caso de la autorización el AccessDecisionManager delega llamado y vota sobre si se debe permitir el la facultad de emitir votos en objetos de tipo acceso a él o no. AccessDecisionVoter. Se proporcionan dos implementaciones de éste último interfaz:

81 Actas del II congreso javaHispano

• BasicAclAfterInvocationProvider permite autenticación se utiliza por tanto denegar el acceso a un objeto después de que DaoAuthenticationProvider, configurándose con una el método se haya invocado, útil cuando no se caché de usuarios basada en EHCache. Por comodidad puede saber a priori. no se ha activado el cifrado de contraseñas, acción que puede realizarse con tan sólo descomentar la línea • BasicAclAfterInvocationollectionFilteringProvider indicada. El gestor de autenticación ProviderManager , similar al anterior, elimina los objetos a los que tan sólo tendrá como proveedor el anteriormente el acceso no ha sido permitido en aquellos mencionado, ya que el único repositorio de usuarios será métodos que devuelven colecciones. la base de datos. Para más detalles sobre ACLs se recomienda consultar el En la aplicación web es necesario añadir dos filtros, completo manual de referencia de Acegi. Acegi Security System for Spring Http Session Integration Filter, que hace que la información de autenticación esté 2 Ejemplo disponible para sucesivas peticiones del usuario al Como ejemplo se utilizará el proyecto ONess [3], guardarla en la sesión, y Acegi Authentication Processing subproyectos user-model y user-webapp. En este Filter para procesar el formulario de login de un usuario. proyecto se ha configurado una aplicación web para El primer filtro no requiere configuración, mientras que proteger sus recursos en peticiones http. Se han omitido el segundo la delega en el contexto de aplicación de partes no relevantes para este ejemplo, pero que pueden Spring, definiendo un bean ser consultadas en la página web y en el repositorio de authenticationProcessingFilter, donde se referencia el código fuente del proyecto, entre otros la configuración gestor de autenticación anteriormente configurado y la necesaria para utilizar autenticación basada en HTTP página a la que ir en caso de error en el login, entre BASIC o CAS o las clases necesarias para ejecutarlo. otros, y authenticationProcessingFilterEntryPoint, donde se configura la página donde se encuentra el formulario Acegi utiliza el contexto de aplicación de Spring para de login. definir la configuración necesaria. Para aquellas personas que no están familiarizados con Spring decir que tan En cuanto a autorización, las decisiones se tomarán sólo es necesario crear un fichero /WEB- basándose en los roles del usuario utilizando RoleVoter, INF/applicationContext.xml con el contenido que se y puesto que tan sólo existe ese AccessDecisionVoter no muestra en la Fig. 1 y añadir a /WEB-INF/web.xml el influirá el gestor de decisiones, optando por un contenido de la Fig. 2. En este segundo fichero se AffirmativeBased. configura un listener que procesa el primero En la aplicación web se configurará un filtro Acegi HTTP automáticamente cada vez que el contenedor de Request Security Filter para restringir el acceso a aplicaciones inicia la aplicación web, y unos filtros que determinadas urls. Este filtro al igual que los anteriores procesan todas las peticiones que llegan. se configura mediante el contexto de aplicación de La autenticación se realiza a través de un objeto de Spring, donde se define un FilterSecurityInterceptor, acceso a datos DAO implementado con el mapeador filterInvocationInterceptor, que define los roles objeto-relacional Hibernate, authenticationDao, para necesarios para acceder a las urls utilizando comodines, acceder a la información de usuarios almacenada en una y se define también securityEnforcementFilter, donde se base de datos. Como alternativa para realizar pruebas enlazan el interceptor, para el caso en el que el usuario también se incluye comentada la definición de un DAO ya está autenticado, y el punto de entrada, para el caso de tipo InMemoryDaoImpl. Como proveedor de contrario.

82 Actas del II congreso javaHispano

5

/ /security_check

false

83 Actas del II congreso javaHispano

false

CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON PATTERN_TYPE_APACHE_ANT /secure/**=ROLE_ADMIN /**/*create*=ROLE_USER,ROLE_ADMIN /**/*edit*=ROLE_USER,ROLE_ADMIN /**/*update*=ROLE_USER,ROLE_ADMIN /**/*delete*=ROLE_USER,ROLE_ADMIN

Figura 1. Spring application context

net.sf.oness.common.webapp.controller.listener.SpringContextLoaderListener

Acegi Security System for Spring Http Session Integration Filter net.sf.acegisecurity.ui.HttpSessionIntegrationFilter Acegi Authentication Processing Filter net.sf.acegisecurity.util.FilterToBeanProxy

84 Actas del II congreso javaHispano

targetClass net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter Acegi HTTP Request Security Filter net.sf.acegisecurity.util.FilterToBeanProxy targetClass net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter

Acegi Security System for Spring Http Session Integration Filter /* Acegi Authentication Processing Filter /* Acegi HTTP Request Security Filter /* Figura 2. web.xml

Otro completísimo ejemplo “contacts” puede encontrarse en la distribución de Acegi Security, Agradecimientos incluyendo autorización basada en listas de control de A Ben Alex, principal desarrollador del proyecto Acegi, acceso, y acceso remoto desde aplicaciones standalone. por su colaboración.

8 Conclusiones Referencias Acegi es uno de los mejores frameworks de seguridad [1] Acegi Security System for Spring existentes en Java, potente y flexible a la vez que sencillo http://acegisecurity.sourceforge.net. de configurar, sin necesitad de modificar código ya [2] Spring Framework http://www.springframework.org. existente y portable entre distintos contenedores de [3] ONess http://oness.sourceforge.net aplicaciones sin necesidad de cambios. Su integración [4] CAS (Central Authentication Service). Universidad de con Spring hace que sea el recomendado para añadir Yale, http://www.yale.edu/tp/auth/. funcionalidades de seguridad a las aplicaciones que [5] Weblog del autor http://www.jroller.com/page/carlossg utilizan ese magnífico framework, cuyo número crece día a día, si bien puede ser utilizado en cualquier tipo de aplicación sin ningún problema.

En este artículo se dado una visión global del framework y se ha mostrado con un ejemplo cómo se pueden proteger las urls de una aplicación web sin necesidad de modificar ni una línea de código. Para mayor información se recomienda la lectura del manual de referencia, realmente completo.

85 Actas del II congreso javaHispano

86 Actas del II congreso javaHispano

Estándares libre y Java: ¿Es el JCP un organismo que crea estándares libres?

Abraham Otero Quintana Dep. de Electrónica y Computación. Edificio Monte da Condesa. Santiago de Compostela, 15768. España [email protected]

es un software concreto, sino un conjunto de Abstract especificaciones que definen todas y cada una de las

La plataforma Java ha sido y es blanco de las críticas de tecnologías que componen la plataforma. Un análisis numerosos activistas de la comunidad del Software acerca de la libertad de la plataforma no puede Libre (SL) por “no ser Software Libre”. Sin embargo basarse en la licencia de una, o varias, de las Java, a diferencia de otras alternativas, no es un implementaciones de un subconjunto de estas software, sino un conjunto de especificaciones que especificaciones, que es en lo que habitualmente la definen una serie de tecnologías. Por ello carece de comunidad del SL basa sus críticas, sino que debe sentido juzgar si la plataforma Java es o no libre en base analizar el proceso de creación y mantenimiento de a la licencia de algunas de las implementaciones de un las especificaciones que definen la plataforma Java. subconjunto de las especificaciones, principal base de Esta tarea, creación y mantenimiento de las las críticas de la comunidad del SL. Lo que deberíamos especificaciones, es responsabilidad de un organismo, plantearnos, dada su condición de especificaciones, es si el Java Community Process (JCP) [1], cuya Java puede considerarse o no un estándar libre. organización y funcionamiento básico se perfilará en

En este trabajo analizaremos el proceso de creación de este trabajo. A continuación se estudiará si las las especificaciones de la plataforma Java para especificaciones creadas por el JCP pueden o no determinar si Java es o no libre. Emplearemos en este considerarse estándares libres. Para ello se tendrán en análisis tanto los criterios de la comunidad del SL, cuenta tanto los criterios de la comunidad del SL, creados bajo la dirección de Bruce Perens, como los creados bajo la dirección de Bruce Perens, como los criterios de la comunidad académica. También se criterios de la comunidad académica, definidos por discutirá la problemática relacionada con la licencia de Ken Krechmer. Irónicamente Java cumple con creces las implementaciones de referencia de la plataforma y los primeros, pero falla en los segundos. se propondrá una solución que busca un equilibrio entre Finalmente, y dado que la licencia de las los intereses de la comunidad del SL y de Sun implementaciones de referencia (IR) parece ser tan Microsystems. importante para el moviendo del SL, se discute este problema. Se mostrará que el miedo a la Keywords: Libertad de Java, estándares libres, Java Community Process, Software Libre. fragmentación con el que Sun se excusa para no liberar su código es infundado. Sun defiende que las

ideas del movimiento del SL, acceder y modificar el 1 Introducción código fuente del software sin restricciones, entran en conflicto con el principio básico de la plataforma Determinar la libertad de la plataforma Java no es Java: “escríbelo una vez y ejecútalo en cualquier sitio” cuestión de analizar las licencias bajo las que se (adaptación de “Write Once Run Anywhere”, WORA). distribuye el conjunto de herramientas de desarrollo Se mostrará que en la práctica no hay evidencias de (JDK), o el entorno de ejecución (JRE) de Sun que esta fragmentación pudiera producirse y se Microsystems, principal fuente de críticas de la propondrá una fórmula mediante la cual Sun podría comunidad del SL hacia Java. La plataforma Java no seguir manteniendo el control de Java a nivel

87 Actas del II congreso javaHispano

empresarial y cobrando royalties por estas tecnologías 3 El Java Community Process (dos ventajas relevantes de Sun sobre sus El Java Community Process [1] es el organismo que competidores empresariales), a la vez que libera el dirige, mediante la creación de nuevas código de las IR. especificaciones y el mantenimiento de las ya existentes, la evolución plataforma Java. El JCP define 2 ¿Qué es la plataforma Java? su propio funcionamiento y las normas por las que se rige, normas que han ido evolucionando desde su Hill Venners en su libro Inside the Virtual Machine [2] creación en Diciembre de 1998. La versión actual del afirma que Java está formado por cuatro piezas JCP, y la que se describe en este documento, es la 2.6 diferentes: una especificación de un lenguaje de [3]. programación; una especificación de un formato binario, los bytecodes; una especificación de una El JCP es administrado por el Program Management máquina virtual, encargada de interpretar los Office (PMO), organismo formado por asalariados de bytecodes; y un conjunto de librerías estándar. Sin Sun Microsystems. Dos Comités Ejecutivos (CE) se duda estos cuatro elementos definen el lenguaje de encargan de aprobar las modificaciones y extensiones programación Java. de la plataforma; uno encargado de las especificaciones relacionadas con J2EE y J2SE Sin embargo, si Java ha alcanzado tanto éxito y (ediciones empresarial y estándar, respectivamente, difusión no es sólo gracias al lenguaje, sino también de la plataforma), y el otro de las relacionadas con al resto de la plataforma, que integra múltiples J2ME (edición para pequeños dispositivos: teléfonos tecnologías en su seno: tecnologías para el desarrollo móviles, tarjetas inteligentes…). Cada uno de estos de aplicaciones Web (Servlets, JSP, portlets, etc.), comités está compuesto por 16 miembros con aplicaciones empresariales (EJB, JTA, JCA, JMS, etc.), derecho a voto, 5 elegidos mediante votación entre aplicaciones para telefonía móvil (CLCD, CDC, OpenGL los miembros del JCP, votación en la que participan ES, etc.), tarjetas inteligentes (JavaCard), y un todos los miembros del JCP. 10 son propuestos por el inmenso sinfín de tecnologías que hicieron a Java PMO, siguiendo los criterios de “comunidad único hasta hace tan sólo un par de años, cuando balanceada” y “representación regional” [3]. Estos apareció .NET. miembros han de ser ratificados mediante votación

El fin de este trabajo no es sólo analizar la libertad del pública. El miembro restante es un representante de lenguaje de programación, y/o del JDK distribuido por Sun. En cada comité hay un segundo representante Sun, sino de toda la plataforma en su conjunto. Por de Sun, que ejerce la labor de presidente, pero que ello, para nuestros objetivos, es más correcto no posee derecho a voto. considerar que la plataforma Java está compuesta por Convertirse en miembro del JCP es gratis para un conjunto de especificaciones, que definen todas y empresas licenciatarias de Sun (empresas que cada una de las partes de la plataforma, y una serie implementan especificaciones de la plataforma con de implementaciones de estas especificaciones. Sin ánimo de lucro y pagan por ello a Sun), y para duda, por ser la base sobre la cual se edifica el resto personas que a título individual deseen formar parte de la plataforma, las especificaciones del lenguaje, del JCP. Las empresas no licenciatarias han de pagar bytecode, máquina virtual, y de las librerías estándar 5000 $ por año. En el caso de organizaciones sin juegan un papel protagonista, pero no son las únicas. ánimo de lucro e instituciones académicas es un comité formado por un miembro de Sun, un miembro del mundo del SL o del mundo académico,

88 Actas del II congreso javaHispano

Figura 1 Diversas etapas por las que pasa un Java Specification Request. y un miembro elegido democráticamente, quien decide individuo con o sin vinculación con el JCP puede si pueden formar parte del JCP gratis, o han de pagar estudiar, opinar y enviar realimentación sobre este 2000 $. borrador al grupo de expertos. En base a la realimentación de la comunidad el grupo de expertos Las incorporaciones de nuevas tecnologías a la realiza modificaciones, completa la especificación y plataforma Java se realizan a través del JCP, mediante un nuevamente hace pública una versión más madura de la “Java Specification Request” [4] (JSR). Para crear un JSR especificación, el “Public Draft”. Nuevamente cualquiera se ha de explicar en un documento la necesidad de la puede enviar realimentación a cerca de este documento, nueva tecnología, o de modificación de una tecnología y el grupo de expertos puede realizar cambios en base a ya existente, y cómo afectará este cambio al resto de la la realimentación. plataforma. Aunque no es necesario, también es recomendable proponer un grupo de expertos que se Cuando se llega a un acuerdo en la especificación ésta encargará de desarrollar el JSR, en caso de ser aceptado. ha de ser ratificada por el CE correspondiente, mediante Cualquiera, sea o no miembro del JCP, puede proponer votación pública en la que necesita una mayoría simple nuevos JSR. Uno de los dos CE del JCP, según el nuevo de los votos emitidos. Si es ratificada pasa a una tercera JSR afecte a J2ME o a J2SE/J2EE, analiza la propuesta y fase, donde es toda la comunidad la que revisa y decide si acepta o no la creación del JSR. Esta decisión se comenta la especificación, mientras que el líder del realiza mediante una votación pública, donde el nuevo grupo de expertos se encarga del desarrollo de la IR y el JSR debe obtener mayoría simple. TC. Una vez que el grupo de expertos ha terminado su trabajo éste, nuevamente, ha de ser aprobado por el CE A continuación el grupo de expertos, normalmente correspondiente mediante una votación pública. liderados por quien propuso el nuevo JSR, trabaja sobre Finalmente se entra en una fase cíclica de la especificación. Deberán completar el documento que mantenimiento de la tecnología, fase también abierta al define la nueva tecnología o modificación de una ya público (ver Fig. 1). existente, una implementación que prueba que la tecnología es factible, denominada Implementación de Hay una serie de JSR en los que Sun tiene privilegios Referencia (IR), y un Test de Compatibilidad (TC), una especiales y que se rigen por unas normas ligeramente batería de pruebas que permite comprobar si una diferentes: los “Umbrella Java Specification Request” implementación cumple o no con la especificación. (UJSR) [3]. Estos son los JSR que definen las tres Tanto la IR como el TC son desarrollados bajo la licencia ediciones de la plataforma: J2SE, J2EE, J2ME y los que el líder del grupo de expertos decida, pudiendo diversos perfiles de J2ME. Estos JSR “paraguas” optar por cualquier licencia libre. protegen, entre otros, la especificación de la máquina virtual, el lenguaje, y el bytecode. Los cambios en estas En una primera fase el grupo de expertos se centra en la especificaciones pueden afectar a la compatibilidad hacia definición la tecnología. Primero debe crear un borrador atrás, o a la portabilidad, de las aplicaciones, por ello de la especificación, “Early Draft”, que se publica en Sun justifica este trato especial. Cualquier nueva Internet y es accesible a todo el mundo; cualquier

89 Actas del II congreso javaHispano

funcionalidad o tecnología que quiera incorporarse a libertad, tanto dentro del mundo del SL como en el cualquiera de las tres ediciones de la plataforma ha de académico, se emplea el término “estándares”. Cabe hacerlo a través de un UJSR. preguntarse qué diferencias hay entre una especificación y un estándar; y si podemos juzgar a las especificaciones Para que un UJSR sea aprobado debe obtener al menos 5 de la plataforma Java con los criterios de los estándares votos positivos del CE correspondiente, y de los votos libres. He aquí una definición de cada uno de estos emitidos al menos dos tercios han de ser de aprobación. términos: Además el representante de Sun puede vetar la nueva especificación, lo que se traduce en que Sun tiene la • Un estándar es una tecnología, formato o método última palabra en lo que se refiere a la aprobación de los desarrollado y adoptado a través de un proceso UJSR, y por lo tanto a cambios sobre J2SE, J2EE y J2ME. abierto de consenso, bajo la guía de cuerpos nacionales (ANSI, BSI, ect.) o internacionales (ISO, No todos los JSR se rigen por las normas aquí descritas; IEEE, etc.) de estándares. como ya se ha comentado el propio JCP es un JSR que evoluciona y por lo tanto sus normas cambian. En un • Una especificación es un conjunto de documentos principio no era tan abierto, no permitiendo, por desarrollados por un grupo dentro de la industria, ejemplo, la implementación de los TC e IR bajo licencias pero sin guías o procedimientos formales que libres. Sun también tenía derechos de veto sobre más aseguren que el trabajo está abierto a cualquier otra JSR, y las implementaciones de las especificaciones parte interesada, o abierto para su revisión y estaban obligadas a respetar las posibles patentes que comentario durante el desarrollo (IETF, WC3, OMG, hubiese en las especificaciones, obligación que ya no etc.). existe en la actualidad. Algunos JSR todavía se guían por En algunas definiciones, como la aquí recogida, se exige versiones anteriores del JCP, siendo el líder del grupo de que un estándar esté aprobado por un organismo expertos el que puede actualizar, si lo considera reconocido oficialmente, un SDO (Standard Definition conveniente, la versión del JCP. Es de esperar que según Organization), mientras que en otras no se especifica el estos JSR saquen nuevas versiones de mantenimiento se tipo de organismo que debe reconocerlo. En otras vayan pasando a la última versión del JCP, más abierta y ocasiones sólo se le requiere que “esté creado a través más respetuosa con el mundo del SL. de un procedimiento abierto que garantice que se Finalmente, cualquiera puede implementar las escucharán toda las partes interesadas y se llegará a un especificaciones, y distribuir su implementación bajo la consenso”. licencia que considere oportuno. No está obligado a Las especificaciones del JCP se definen entre más de 700 pasar el TC, pero si desea hacerlo (esto es imprescindible organizaciones e individuos, entre la cuales se hallan si se desea emplear la marca registrada “Java” y términos todas las grandes empresas de informática menos relacionados), y ha realizado la implementación con Microsof; están abiertas a todo el que las quiera ánimo de lucro, ha de pagar a Sun por pasar el TC. Si la examinar; cualquiera puede participar gratuitamente en implementación ha sido realizada por una organización el JCP, y por lo tanto en la definición y evolución de la sin ánimo lucro, como suele ser el caso de los desarrollos plataforma; e incluso sin pertenecer al JCP se puede libres, el mismo comité de tres personas que decide si las contribuir al proceso de definición de las organizaciones sin ánimo de lucro pagan por pertenecer especificaciones. No parece justo caracterizar de al JCP, decide si ha de pagar o no por pasar el TC. No “especificación” (al menos en el sentido de cierta pasar el TC no implica que una determinada bibliografía), a algo que es consensuado entre tantas implementación no cumpla la especificación, sin partes, con garantías de acceso, transparencia, y con embargo es una garantía para sus usuarios de que posibilidad de participación sin discriminación en su efectivamente la cumple. construcción. Por otro lado en la bibliografía sobre estándares libres se trata a las especificaciones del JCP 3.1 Estándares vs especificaciones como “estándares” [5].

El nombre que recibe la documentación que define las Evitaremos entrar más en discusiones lingüísticas y, dado tecnologías que forman la plataforma Java es el carácter consensuado y abierto de las especificaciones “especificaciones”; sin embargo cuando se habla de del JCP las trataremos como “estándares”, aún cuando

90 Actas del II congreso javaHispano

no estén reconocidas por organismos de estándares implementación; esto último es casi imprescindible para oficiales. El motivo principal para ello es la lentitud de la el mundo del SL, que no puede permitirse pagar royalties evolución de los estándares en los organismos oficiales. por usar el estándar, ni afrontar largos y costos juicios. En su día Sun consideró llevar a ISO las especificaciones Un estándar libre respeta la libertad de elección: del JCP, pero lo descartó porque ISO ralentizaría podemos tomar hoy una decisión y mañana otra demasiado la evolución de la plataforma: más de un diferente: si desarrollamos una web con ASP .NET nos estándar definido dentro de ISO u organismos similares ataremos a un servidor web y a un sistema operativo. Si se ha quedado obsoleto antes de llegar a ver la luz. empleamos JSP o php podremos cambiar en cualquier momento de servidor web, ya que hay múltiples 4 Importancia de los estándares libres vendedores e implementaciones libres que los soportan, La interoperabilidad, capacidad de un sistema para y/o de sistema operativo. trabajar con otro, es una de las características más Incluso las más “pequeñas” estandarizaciones libres han deseables para cualquier aplicación informática. De poco permitido enormes avances. Por ejemplo, fueron los nos valdría un cliente de correo que no siga el protocolo estándares libres como TCP/IP, FTP, HTML, SMTP, etc. los SMTP, un procesador de textos cuyos documentos sólo que permitieron construir el único “caso de éxito” se pudiesen visualizar y editar en la máquina donde se auténtico en lo referente interoperabilidad: Internet. A crearon, o un servidor web que no respeta el protocolo principios de los años 90 en las redes empresariales http. En el pasado era posible concebir un sistema coexistían un conjunto de protocolos propietarios para la informático que no interoperaba con ningún otro comunicación en red entre las máquinas de distintos sistema; sin embargo en la era de Internet, donde fabricantes (IBM, Apple, Microsoft, VAX, ect.) entre los proliferan múltiples aplicaciones distribuidas que son cuales era difícil interoperar. En este contexto Internet se accedidas por múltiples dispositivos de diversa abre a las empresas y trae consigo TCP/IP, un protocolo naturaleza (PCs, PDA, terminales móviles de última libre para la comunicación en red, y un conjunto de generación, mainframes…) no hay lugar para este tipo protocolos libres para interoperar entre equipos (FTP, de islas. Telnet, ect.). No le llevó mucho tiempo imponerse a los El software libre por sí sólo no genera interoperabilidad; otros protocolos propietarios siendo clave en su triunfo los estándares son la base para conseguirla. De aquí la la apertura del estándar, y el no tener que pagar ningún enorme importancia de contar con estándares libres, tipo de royalties para emplearlo. para invitar que estándares propietarios coarten la Un estándar libre fomenta la aparición de múltiples libertad del software, aún cuando su código fuente sea implementaciones de características heterogéneas, libres libre. Los estándares propietarios, o el no uso de y comerciales. Esto beneficia al usuario final, ya que se estándares, es un mecanismo para entorpecer e incluso evita el “vendor lock-in”, quedar atrapado por un anular el desarrollo de soluciones de terceros (en especial proveedor del que dependo por haber basado mi las libres). Así por ejemplo los desarrolladores de solución en su producto. OpenOffice se ven obligados a hacer reingeniería inversa para acceder a los formatos OLE de Microsoft, y se Tras estos argumentos cabe hacerse una pregunta: exponen a ser demandados por sus actividades. De un ¿Hasta que punto es “libre” un software cuyo código modo similar los desarrolladores de clientes de fuente es libre pero que implementa un estándar mensajería libres que interactúan con la red MSN cada propietario? Podremos modificar su código fuente, pero vez que surge una nueva versión del protocolo MSNpX lo hacemos siempre dentro de la jaula (formato o deben reventarlo y actualizar los clientes; y Microsoft protocolo) que define el estándar propietario, que no podría cerrar la red de MSN, impidiendo que clientes de controlamos y al que estamos obligados a ceñirnos. terceros, libres y no libres, se conecten a su red. Podría darse el caso de que el dueño del estándar propietario ponga trabas, o impida, el desarrollo del Un estándar libre debe poder implementarse libremente. producto libre. Un software “libre”, en el sentido más Para ello su contenido ha de ser público y accesible, general de la palabra, debe basarse en estándares libres. eliminando las barreras de tipo técnico en la implementación. Tampoco deben existir barreras de tipo económico o legal (patentes y copyright) que impidan su

91 Actas del II congreso javaHispano

4.1 ¿Qué es un estándar libre? Los criterios sobre los que trabaja Perens constituyen el intento más serio y consensuado de la comunidad del SL Dentro de la comunidad del SL no hay una definición para definir qué es un estándar libre, por ello los globalmente aceptada sobre qué es un estándar libre. emplearemos como base del análisis que realizaremos. Así, por ejemplo, ni Free Software Foundation (FSF) [6], No obstante en este estudio añadiremos algunas ideas ni Open Source Iniciative (OSI) [7] proporcionan criterios del trabajo de Krechmer a los criterios de Perens, por bien definidos para determinar si un estándar es o no considerar que éstas los complementan. libre. El mayor esfuerzo en la definición de estos criterios, dentro del mundo del Software Libre, está liderado por Bruce Perens y desarrollado en el entorno 5 ¿Está la plataforma Java compuesta de Debian. Perens es uno de los principales líderes del por estándares libres? movimiento del SL, en el cual milita desde 1987; cofundador de Open Source Iniciative es el autor del En este apartado analizaremos el proceso de creación y manifiesto “Open Source Definition”. Actualmente hay mantenimiento de los JSR así como las condiciones bajo un borrador con el trabajo realizado hasta la fecha en las cuales se puede acceder a ellos e implementarlos, [8]. para determinar si Java puede o no considerarse un estándar libre. Otro trabajo interesante es el de Ken Krechmer, “The Principles of Open Standards” [9]. Krechemer, a diferencia de Pernes, no es un activista del Software 5.1 Criterios de Perens Libre. Su trabajo está orientado a organizaciones El borrador creado por Pernees [8] en colaboración con sensiblemente diferentes del JCP, como ISO o ECMA, que el entorno de Debian define una serie de requerimientos también estandarizan objetos materiales y tangibles, y que debe cumplir un estándar para considerase un no sólo software, algo que se puede replicar y trasladar “estándar libre” (open standard). Además identifica una de un punto a otro del planeta a coste prácticamente serie de buenas prácticas, a modo de recomendaciones, cero. Por ello no todas las ideas que hay tras los criterios para los estándares libres, buenas prácticas que no se de Krechemer poseen sentido en el mundo de lo exigen para poder considerarse como libre. Analizaremos intangible. Sin embargo hay algunas ideas que sí punto por punto cada uno de los requerimientos podemos tomar prestadas, ideas que no están presentes descritos en este documento. En las siguientes entre las de Perens y que, desde el punto de vista de subsecciones el contenido en cursiva es un resumen, que autor, son de gran importancia en la definición de qué es no una traducción, del contenido de cada uno de los un estándar libre; dicho de otro modo: son carencias del puntos del documento de Perens. borrador de Perens.

Al margen de estos trabajos existen varios portales 5.1.1 Disponibilidad: dedicados a los estándares libres, pero ninguno de ellos Un estándar libre debe estar disponible para leer e define de un modo concreto y preciso qué es un implementar por cualquier individuo u organización. Se estándar libre, y se hallan muy lejos de tener un peso recomienda como buena práctica que la documentación equivalente a que FSF u OSI tienen sobre el SL. y la IR del estándar estén disponibles en Internet. No se OpenStandards.org [10] es una web creada a principios hace ninguna referencia a la licencia del código fuente del 2000 con un propósito no muy claro y que en la de la IR. actualidad está abandonada, sin que nunca haya tenido actividad real. OpenStandards.net [11] es un escaparate La documentación de cualquier JSR está disponible en de noticias de otros sitios web y un almacén de enlaces Internet, y cualquiera puede descargársela e que carece de contenidos propios. Mención a parte implementarlo. En cuanto a la IR de referencia de un JSR, merece Free Standards Group [12], dedicado a crear y su test de compatibilidad, son siempre accesibles de un estándares para el mundo Linux. Poseen certificaciones modo gratuito para un individuo u organización sin de gran reconocimiento, como LSD (Linux Standard ánimo de lucro. Base), OpenI18n, OpenPrinting, etc. Sin embargo sus interesantes objetivos, crear estándares para Linux, no coinciden con los que se persiguen en este trabajo.

92 Actas del II congreso javaHispano

5.1.2 Maximizar la elección del usuario final 5.1.4 No discriminación:

Los estándares abiertos deben generar un mercado No se puede favorecer a ninguna implementación sobre competitivo permitiendo un amplio rango de otras: la certificación ha de ser justa y sólo basarse en implementaciones, con precios que varíen “desde muy motivos tecnológicos. altos a nulos”. En la actualidad sólo se tienen en cuenta motivos Evitar el “vendor lock-in” es uno de los principios básicos tecnológicos para pasar los TC. Esto no fue así hasta sobre los que se ha construido la plataforma, así como hace unos meses, cuando entró en vigor JCP 2.6; hasta una de sus principales ventajas frente a otras tecnologías entonces una implementación libre de un UJSR no podía propietarias. En la práctica, efectivamente podemos certificarse por el tipo de licencia de su código fuente. encontrar costosas implementaciones empresariales de las especificaciones (Ej.: BEA WebLogic, IBM WebSphere 5.1.5 Extensión o subconjunto: ~100.000 $ por CPU) e implementaciones libres Los estándares libres se pueden extender u ofrecer en completamente gratuitas (Ej.: JBoss, JOnAS, Gerónimo). subconjunto, aunque en este caso puede negarse la certificación. 5.1.3 Sin Royalties: Es posible implementar subconjuntos, superconjuntos, o Debe ser posible implementar una especificación sin modificaciones de las especificaciones del JCP; por pagar royalties. Para garantizar que esto será siempre así ejemplo en [14] se recogen múltiples variaciones del (evitar posibles patentes submarinas) cualquier patente lenguaje Java, bytecode y/o JVM, normalmente incluida en el estándar debe poderse implementar de un desarrolladas con fines científicos. En general no es modo totalmente libre de royalties. Perens acepta que la posible certificar subconjuntos ni modificaciones de las certificación del estándar pueda requerir pagar, y especificaciones, aunque sí superconjuntos de ciertas recomienda (aunque no exige) proporcionar un camino especificaciones. Así, por ejemplo, los distintos para la auto-certificación. vendedores de servidores de aplicaciones J2EE suelen Todas las patentes involucradas en un JSR deben extender la especificación con características propias “garantizar una licencia perpetua, no excluyente, para diferenciar sus productos de los de la competencia. mundial, sobre la cual nunca se podrá exigir ningún pago (fully paid-up), libre de royalties e irrevocable” [13] 5.1.6 Defensa contra prácticas predatorias a quien las implemente. Este punto es una concesión más que un requerimiento. La certificación de compatibilidad requiere pagar cuotas Los estándares libres pueden protegerse contra a Sun, pero los TC son accesibles gratuitamente para modificaciones por parte de terceras partes para evitar individuos y organizaciones sin ánimo de lucro [13], por prácticas “embrace-and-extend”. Este tipo de prácticas lo que es posible auto-certificarse. Además existe un las suele llevar a cabo el vendedor predominante de un camino para la certificación gratuita de estándar, el cual crea una extensión del estándar no implementaciones libres y sin ánimo de lucro: el servidor compatible con el original e impide mediante patentes y de aplicaciones J2EE JOnAS se certificó completamente copyright que los demás vendedores implementen estas gratis, y Geronimo lo hará en breve en las mismas extensiones. Esto provoca que las implementaciones de condiciones. los demás vendedores no sean compatibles con las del vendedor predominante y permiten a éste último crear El código de la IR (y del TC) debe estar disponible bajo un monopolio sobre el estándar. condiciones RAND (Reasonable And Non Discriminatory) [10], o más permisibles, para basar en ella otras Dentro de los JSR, o del JCP, no se identifican defensas implementaciones. Como se discute en [5] las contra ese tipo de prácticas. No obstante la certificación condiciones RAND en la práctica pueden no ser de las implementaciones, así como la propiedad de Sun razonables y sí suelen ser discriminatorias; sin embargo de la marca “Java” y términos relacionados, que sólo se que el código esté disponible bajo condiciones no más pueden emplear tras certificarse, defienden a la restrictivas que RAND es mejor que ningún tipo garantía. plataforma de estas prácticas. Esto es lo que sucedió en 1998 con la JVM de Microsoft [15], que no seguía la

93 Actas del II congreso javaHispano

especificación de J2SE, por lo que Sun llevó a la requerimientos. Veamos cuales son los requerimientos compañía de Redmon a los tribunales. añadidos.

5.2 ¿Se cumplen los criterios de Perens? 5.3.1 Apertura:

El draft de Perens es el intento más serio y consensuado Todas las partes interesadas pueden participar en el que la comunidad del SL ha realizado para definir qué es desarrollo del estándar. un estándar libre. Como se ha mostrado, las Cualquier individuo puede formar parte del JCP, ya bien especificaciones de la plataforma Java cumplen todos los sea a título personal o como representante de una requerimientos de este borrador, todas sus buenas empresa u organización. En el caso de las organizaciones prácticas y en varias ocasiones incluso van más allá, por sin ánimo de lucro e individuos esta participación es ejemplo, ofreciendo una certificación completa gratuita completamente gratuita. Por otro lado, incluso sin a implementaciones sin ánimo de lucro. participar en el JCP se puede participar en la definición En base a los criterios de Perens la plataforma Java, un de un único JSR, e incluso sin estar directamente conjunto de especificaciones que definen una serie de involucrado en el JCP, o en uno de sus JSR, cualquiera tecnologías, es libre. Esto no quiere decir que todas las puede acceder a la documentación de todos los JSR implementaciones de cada tecnología se distribuyan bajo mientras se están desarrollando, y enviar realimentación una licencia libre, pero la licencia de las al grupo de expertos. implementaciones nada tiene que ver con la libertad del estándar; de hecho Perens nunca la menciona en sus criterios. 5.1.6 Consenso y proceso de decisión justo:

Estos requerimientos no son suficientes, desde el punto En el proceso de definición del estándar todos los de vista del autor, para considerar un estándar libre. intereses son discutidos y se llega a un acuerdo sin Podrían definir un estándar “accesible”: puedo acceder a dominación. Una votación puede ser empleada para él e implementarlo libremente, pero esto no es encontrar una solución. suficiente: la única libertad que se garantiza es la de seguir un camino (el marcado por el estándar) que Todos los intereses y contribuciones de las distintas podría haber sido definido por una sola parte interesada partes son considerados y discutidos en el JCP, y la (empresa, organización o individuo), y no por todas las votación, de los CE, es la que finalmente decide qué se partes interesadas. Por ello, para completar este estudio, incorpora y qué no se incorpora a las especificaciones añadiremos dos criterios del documento de Krechmer a que forman la plataforma. los definidos por Perens. Sin embargo siempre hay un miembro de Sun Microsystems en cada CE, que tiene derecho de veto 5.3 Criterios de Krechmer sobre todos los UJSR, y de los restantes 15 miembros 10 son propuestos por Sun, aunque deben de pasar una Krechmer, a diferencia de Perens, es un investigador del ratificación pública. El PMO, aunque es un mero órgano laboratorio de Palo Alto, en California, USA. Su trabajo administrativo, está compuesto por asalariados de Sun, y ganó un premio en la competición “World Standards siempre hay un miembro de Sun en el comité de tres Day” de 1998 y fue publicado en la revista Standards personas que decide si una organización sin ánimo de Engineering. Este trabajo aborda la problemática de los lucro puede o no pertenecer gratis al JCP o pasar el TC estándares en general, no sólo informáticos, y se escribió sin pagar. Este criterio no se cumple por los privilegios pensando en organizaciones muy diferentes del JCP, de uno de los participantes en el proceso de definición como ISO o ECMA, que también estandarizan objetos de las especificaciones: Sun Microsystems materiales, y no sólo software. Por ello no todas las ideas que hay tras los criterios académicos poseen sentido en La solución a esta falla podría pasar por la gestión del el mundo de lo intangible, y algunos requieren cierta JPC por un organismo independiente, estilo Apache adaptación. Software Foundation. Esto evitaría que la plataforma se mueva en una dirección que no es la más conveniente No obstante, en líneas generales, los criterios de para todas las partes interesadas, por causa de los Krechemer incluyen a los de Perens y añaden más

94 Actas del II congreso javaHispano

intereses particulares de una empresa. Todos los lenguaje de programación en Sourceforge, estando muy miembros de los CE deberían elegirse de un modo cerca de de los primeros, C y C++; y existen una gran democrático y debería desaparecer el derecho de veto. cantidad de implementaciones libres de especificaciones Java, suficientes para construir una compleja y completa solución empresarial [21]. 6 Implementaciones de Referencia y Software Libre Cabe preguntarse porqué siendo la comunidad Java una de las más prolíficas desarrollando SL las Resulta evidente que la comunidad del SL se beneficiaría implementaciones libres del entorno base van tan lentas. de poseer un código libre en el que basar sus La respuesta posiblemente sea que esta prolífera implementaciones de las especificaciones, y es deseable comunidad, dado que dispone de varias que este código fuese el de las propias IR. Por un lado implementaciones gratuitas del entorno base que éstas son la primera implementación que se desarrolla, lo poseen una calidad contrastada, prefiere centrarse en que permitiría a la comunidad del SL disponer del código desarrollar aplicaciones de más alto nivel, como librerías, base rápidamente. Por otro, si las todas las IR fuesen aplicaciones de escritorio, servidores de aplicaciones, etc. libres serían testadas por multitud de desarrolladores, lo que tienen un beneficio comparativo mucho mayor para que redundaría en una mejora de su portabilidad y su la sociedad. No obstante esta situación podría cambiar calidad, y por consiguiente en la portabilidad y calidad en breve, debido a la intención del gobierno de Brasil de de las demás implementaciones: Jason Hunter afirma desarrollar una implementación libre de J2SE [21], que que desde que Tomcat es la IR de los motores de Servlets esperan tener lista para finales del 2005. De cumplirse se han eliminado muchos bugs de portabilidad en los este objetivo el año 2005 podría ser el año en que la motores comerciales. comunidad del SL deje a un lado sus reparos y abrace definitivamente a la plataforma Java. La licencia de las IR desarrolladas por Sun son la principal fuente de críticas a Java por parte del mundo del SL. Sin La IR del J2SE, así como otras IR desarrolladas por Sun, embargo, como hemos mostrado, Java no es un se distribuyen bajo licencia Sun Community Source software, sino un conjunto de especificaciones. Alguna License (SCSL) [22]. Esta licencia permite ver el código de las implementaciones de estas especificaciones son fuente del desarrollo, e incluso modificarlo, pero sólo libres, otras no, pero esto no guarda relación con la bajo ciertas condiciones, las cuales, en esencia, fuerzan a libertad de las especificaciones. Decir que Java no es libre que el producto modificado siga cumpliendo las porque una de las implementaciones de una especificaciones de la máquina virtual, bytecode y especificación no licencia su código fuente mediante una lenguaje Java. Su objetivo es evitar que la plataforma se licencia libre es tan incoherente como decir que el fragmente por causa de implementaciones del protocolo http no es libre porque Internet Explorer e compilador o máquina virtual no compatibles con las Internet Information Server no son libres. especificaciones. Sun afirma que esta licencia “toma las ventajas de los modelos de código abierto y propietarios, La IR más polémica es sin duda la de J2SE. Efectivamente y elimina sus inconvenientes” [22], ya que permite la implementación de Sun no es libre, ni la de IBM, acceder al código fuente libremente, con todos los BlackDown, Bea, etc. Sin embargo Kaffe [16], GCJ [17], beneficios que para la comunidad y para la propia GNU Classpath [18], Japhar [19], Jikes [20], etc. sí son plataforma conlleva, siempre que el acceso no atente libres, si bien es cierto que ninguna de ellas tiene en la contra el principio básico de WORA. actualidad una funcionalidad suficiente para resultar atractiva a los desarrolladores. En este sentido es la Sin embargo, una vez que un individuo ha accedido al propia comunidad del SL quien, por la causa que fuere, código licenciado SCSL esta licencia le impide participar está fallando a la hora de proveer una alternativa libre a en proyectos de código abierto, ya que el código que ha este estándar, del mismo modo que esta comunidad ha visto es propiedad intelectual de Sun y no puede creado alternativas libres para otros estándares (Mozilla emplear en proyectos libres lo que en él ha aprendido. y Apache web server en el caso de http, por ejemplo). Además, si desea cobrar a sus usuarios por el trabajo que ha realizado está obligado a pagar cuotas a Sun. En general el SL goza de un excelente estado de salud en Evidentemente una licencia así dista mucho de poder la plataforma Java: a pesar de ser un lenguaje de considerarse libre. programación relativamente reciente es el tercer

95 Actas del II congreso javaHispano

¿Es necesaria una licencia de este tipo para algunas IR, comiendo el terreno de los servidores SPARC y Solaris. para proteger a la plataforma Java de la fragmentación? Sun con Solaris10, un sistema operativo de código libre Es una pregunta difícil de responder. Sun afirma que sí; que sale al mercado con una agresiva campaña de sin ella algunas empresas podrían aprovecharse de su precios que intenta competir con los servidores Linux de posición privilegiada en el mercado para imponer una RedHat, junto con la venta de hardware de bajo precio versión de la máquina virtual devaluada, o no basado en la arquitectura , va a tratar de cambiar compatible con las demás. Este fue el caso de Microsoft, esta tendencia; pero el éxito de su nueva estrategia no quien en su día desarrolló una versión de la máquina está garantizado. virtual y herramientas de desarrollo que permitían En respuesta a esto Sun, una compañía que acceder a ciertos servicios de Windows, lo que daba tradicionalmente vivía del hardware, está apostando lugar a crear aplicaciones que sólo funcionaban en este fuertemente por los negocios basados en el software y sistema operativo [15]. Si la plataforma Java hubiese sido los servicios. El centro del negocio del software en Sun es completamente abierta nada hubiese podido detener a Java: recientemente hemos visto como Sun ha cambiado Microsoft. Hoy en día la plataforma estaría fragmentada; el nombre de varios de sus productos para incluir el más de la mitad de los desarrolladores Java desarrollan nombre Java en ellos: Java Entreprise System, Java Studio bajo Windows, y probablemente buena parte de ellos Creator, Application Server, Java emplearían las herramientas de Microsoft. Según Sun Desktop System. En el último la palabra Java se incluyó SCSL vela para que esto no suceda. en el nombre sólo como marketing, ya que Java Desktop Sin embargo Microsoft, u otra gran empresa, y la System es un S.O. de escritorio basado en Linux que comunidad de SL tienen recursos suficientes para poco tiene que ver con Java. Menos aún tienen que ver implementar la máquina virtual desde cero, sin las Sun Java , unas estaciones de trabajo con necesidad de basarse en ningún código. Es posible partir procesadores Opteron que no incluyen ningún tipo de de las especificaciones del lenguaje y máquina virtual optimización para Java. [24, 25] e implementar una variante de Java sin basarse Por otro lado, Sun actualmente obtiene una cantidad de en ningún código, con lo que esta licencia pierde ingresos considerable por las licencias de las tecnologías bastante sentido. Java; y su control sobre Java puede ayudarle a Por otro lado no hay ningún indicio de fragmentación posicionarse en un mercado emergente que a medio dentro de la comunidad del SL: las implementaciones plazo alcanzará un notable volumen: J2ME. Esto sin libres de J2SE (y de cualquier otro JSR) siempre tratan de olvidar el prestigio que le da a la compañía haber creado adherirse a las especificaciones. y controlar la que actualmente es la principal tecnología para crear aplicaciones de servidor y para dispositivos Sun a menudo alega que las múltiples distribuciones de móviles. Linux prueban la comunidad del SL no es capaz de reconocer que hay cosas que si se bifurcan pierden su Siendo razonable, las empresas no son ONGs, no es valor. Sin embargo parece que Sun se olvida del lógico que Sun desperdicie su posición ventajosa, tremendo esfuerzo que esta comunidad realiza a través respecto a sus competidores y no explote una tecnología de Free Standards Group [12] para lograr que todas las en la que ha invertido tanto. A primera vista parece que distribuciones de Linux, y otros sistema operativos *nix, el mundo del SL busca un control sobre Java que sigan una serie de estándares que garanticen la probablemente Sun no se pueda permitir ceder en este compatibilidad entre distribuciones; y es que la momento sin dañar gravemente sus intereses. comunidad del SL sabe reconocer y respetar ciertas Desde el punto de vista del autor existe un punto de cosas qué no se deben fragmentar. encuentro entre Sun y la comunidad del SL, que puede En la práctica no hay indicios de que liberar el código permitir al primero seguir controlando Java a nivel fuente de las IR suponga un riesgo de fragmentación empresarial, y al segundo disponer del código fuente de para la plataforma. Desde el punto de vista del autor lo las IR. Este punto de encuentro es licenciar el código que realmente detiene a Sun es un problema de SCSL mediante una doble licencia [26]. Un software que naturaleza muy diferente: Sun, como empresa, necesita se distribuye mediante una doble licencia se libera bajo Java, y necesita controlar Java a nivel empresarial. Las dos licencias, una libre con un “copyleft” [27] muy plataformas Intel y compatibles, junto con Linux, están fuerte (GPL o similar) y una propietaria. La libre satisfaría

96 Actas del II congreso javaHispano

todas las demandas del mundo del SL, sin embargo no incluso se incentiva dando opción a certificarse sería aceptable, en general, para las empresas: éstas gratuitamente, un rechazo frontal a cualquier patente no verían su código infectado por el efecto “virus” de la licenciada Royalty Free en los JSR, y una auto-limitación licencia con copyleft y tendrían que liberar su propio de los privilegios de Sun. desarrollo bajo una licencia libre. Dado que muy pocas empresas estarán dispuestas a ello se verán obligadas a optar por la licencia propietaria, y de este modo Sun 7 Conclusiones seguiría obteniendo beneficios y controlando Java a nivel La plataforma Java, un conjunto de especificaciones que empresarial. definen una serie de tecnologías, según los criterios Al mismo tiempo Sun gana el apoyo de la comunidad del recogidos en el borrador de Perens, principal esfuerzo SL y garantiza que toda distribución de Linux incluya del mundo del SL para definir qué es un estándar libre, una JVM. A su vez la comunidad del SL obtiene un es libre. En este análisis las licencias de las IR, u otras valioso código en el cual basar sus desarrollos; dejaría de implementaciones, carecen de relevancia; de hecho tener reticencias sobre si algún día Sun empieza a cobrar nunca se mencionan estas licencias en el documento de por Java o cambia sus condiciones de distribución; y Perens. Extendiendo estos criterios del modo que al tendría garantías de que Java no se vería afectado por autor le ha parecido adecuado, se identifica un una hipotética opa hostil, o cualquier otra adversidad, problema: los privilegios que Sun posee sobre el JCP. A que pueda padecer Sun y hacer que la propiedad pesar de ello no hay constancia de que Sun los haya intelectual relacionada con la plataforma Java cambie de empleado con otro fin distinto de velar por la dueño. plataforma.

Liberar el código SCSL bajo una doble licencia (SCSL y 6.1 Unas palabras a favor de Sun GPL, por ejemplo) beneficiaría tanto al mundo del SL como a Sun. Haría que Java fuese mejor acogido y Sun a lo largo de los años ha mostrado, tanto tuviese más apoyos dentro de la comunidad del SL, con verbalmente como con sus acciones, que sus privilegios los consecuentes beneficios para la plataforma, y por sobre la plataforma Java son para hacer frente a ataques, extensión para Sun; habría más desarrollos libres en y como sucedió en el caso de Microsoft, y no poner trabas para Java; y el código de las IR estaría más chequeado, lo al desarrollo de SL en la plataforma Java. Durante mucho que incrementaría la portabilidad y fiabilidad de las IR y tiempo Apache violó las normas del JCP, pudiendo haber de todas las implementaciones que se basan en ellas. sido demandada por Sun. Lejos de ocurrir esto Apache mantenía una excelente relación con Sun, quien le Por su parte Sun seguiría controlando y obteniendo apoyaba y financiaba sus desarrollos libres, y todos los beneficios de Java a nivel empresarial, ya que la mayor problemas se zanjaron modificando el JCP para legalizar parte de las empresas no optarían por la licencia libre las actividades (desarrollo de una IR y TC bajo licencias por su efecto vírico. Sun podría ganar el apoyo del libres) que Apache llevaba tiempo realizando, pero que mundo del SL sin perder su posición privilegiada en el de ningún modo suponían un riesgo para la mercado Java. fragmentación de la plataforma.

Si bien Sun posee privilegios en el JCP al autor no le consta ninguna evidencia de que los haya empleado con otro fin que no fuese proteger la compatibilidad y Agradecimientos portabilidad de la plataforma. Deseo expresar mi agradecimiento a Alvaro-Sánchez También es evidente que Sun empuja cada vez más la Mariscal, Alberto Molperceres y Martín Pérez. Sin los plataforma Java hacia la liberación: cada nueva versión trabajos que vosotros realizasteis antes que el mío, sin del JCP “libera” un poco más la plataforma. El JCP ha las discusiones que hemos mantenido y sin la ido evolucionando desde un estado en el que no era realimentación que he recibido de vosotros este trabajo posible realizar IR bajo licencias libres, los JSR podían probablemente nunca habría visto la luz. contener patentes y Sun poseía notables privilegios, hasta una tolerancia total con el mundo del SL, al cual

97 Actas del II congreso javaHispano

Referencias

[1] Java Community Process, http://jcp.org. [2] Bill Venners. Inside the Java Virtual Machine. McGraw-Hill Osborne Media, 2000. [3] JCP 2.6, http://jcp.org/en/jsr/detail?id=215. [4] Java Specification Request, http://jcp.org/en/jsr/overview. [5] Robin Cover. Patents and Standars, http://xml.coverpages.org/patents.html. [6] Free Software Foundation. http://www.fsf.org. [7] Open Software Iniciative. http://www.opensource. org. [8] Bruce Perens et al. Open Standards Principles and Practice. http://perens.com/OpenStandards/Definition.html. [9] Ken Krechmer. The Principles of Open Standars, http://www.ses-standards.org/library/krechmer.pdf. [10] OpenStandards.org. http://www.openstandards.org/. [11] OpenStandards.net. http://www.openstandards.net/. [12] Free Standards Group. http://freestandards.org/. [13] Java Specification Participation Agreement, http://jcp.org/aboutJava/communityprocess/JSPA2.pdf. [14] Múltiples variaciones del lenguaje Java, bytecode y JVM. http://www.robert-tolksdorf.de/vmlanguages.html. [15] Declaración de James Gosling en el juicio contra Microsoft por su implementación fraudulenta de la JVM. http://java.sun.com/lawsuit/82198gosling.html. [16] Kaffe, http://www.kaffe.org. [17] GCJ, http://gcc.gnu.org/java/. [18] Classpath, http://www.gnu.org/software/classpath/. [19] Japhar, http://www.japhar.org. [20] Jikes, http://www- 124.ibm.com/developerworks/oss/jikesrvm/ [21] Alberto Molpeceres y Martín Pérez. Arquitectura empresarial y software libre, J2EE. http://www.javahispano.org/articles.article.action?id=70. [22] Noticia de javaHispano. http://www.javahispano.org/news.item.action?id=673049 882 [23] Sun Community Source License (SCSL), http://www.Sun.com/software/communitysource. [24] Tim Lindholm y Frank Yellin. The JavaM Virtual Machine Specification. Addison Wesley. 1999. [25] J. Gosling, B. Joy, G. Steele, G. Bracha. The Java Language Specification. Addison Wesley. [26] Mikko Valimaki, Dual Licensing in Open Source Software Industry. http://www.soberit.hut.fi/~msvalima/dual_licensing.pdf. [27] What is copyleft? http://www.gnu.org/copyleft/copyleft.html.

98 Actas del II congreso javaHispano

Caso de uso: Empleo de tecnologías J2EE para el desarrollo de una plataforma

Rafael Pedraza Carmona Alberto Planas Domínguez Antonio Navarro González [email protected] SEIRC/CESEAND [email protected] [email protected] Benjamín de la Fuente Ranea Jose David Fernández Rodríguez [email protected] [email protected]

pertenecen al Departamento de Desarrollo. Los primeros Abstract productos se realizaron exclusivamente con tecnología

En esta presentación se pretende explicar la experiencia de Microsoft (Visual Basic for Applications); si bien al que ha supuesto el desarrollo de una plataforma para la principio nos beneficiamos de la facilidad y simplicidad gestión de ofertas y demandas tecnológicas, desarrollada de esta tecnología, pronto nos vimos en un callejón sin para dos organismos dependientes de la Consejería de salida: acorralados por unas necesidades y Innovación, Ciencia y Empresa de la Junta de Andalucía. El especificaciones crecientes en complejidad y al mismo objetivo principal de esta plataforma es servir de nexo de tiempo limitados por unas herramientas que no nos unión entre aquellas empresas, grupos de investigación u proporcionaban soluciones cuando pretendíamos otros organismos que ofrecen algún producto con marcado obtener algún resultado más allá de los casos de uso carácter innovador y aquellas otras que pueden ser más simples. Problemas de escalabilidad y la consumidores de estas tecnologías. obsolescencia de la tecnología empleada no nos deja otra alternativa que pegar el salto tecnológico. Las características más reseñables de este proyecto son el uso en exclusiva de tecnologías de código abierto, el A la hora de tomar la decisión de hacia donde mover empleo de las especificaciones J2EE para el módulo de nuestro marco de desarrollo los factores determinantes servidor (basado en JBoss, Tomcat, Axis, Lucene,...), el para elegir J2EE y software libre, fueron razones innovador sistema de seguridad que facilita el acceso económicas (soluciones de Oracle, IBM y BEA son segmentado a la información, un workflow para el control excesivamente caras en un principio) y tecnológicas de distintos grupos de trabajo y el desarrollo de una (posibilidad de acceder al código y modificarlo, creciente interface de cliente Java basado en la plataforma Eclipse 3. madurez de la tecnología, masa crítica de desarrolladores, Java como lenguaje común para La conjunción de todas estas tecnologías, con el lenguaje aplicaciones de servidor y de cliente, presencia de J2EE Java como hilo conductor, puede suponer un importante en la industria frente a otras soluciones). punto de referencia para otros desarrolladores que pretendan alcanzar un alto nivel tecnológico, basándose Esta apuesta de futuro tenía que como consecuencia el para ello en la potencia y seguridad que aportan los destinar recursos en tiempo y económicos a desarrollos de código abierto. investigación, partida para la que hasta ese momento no había existido presupuesto.

Keywords: J2EE, JBoss, JavaCC, Eclipse, Lucene, Hylafax, 2 Nuestro primer cliente: descripción del Software Libre, Seguridad. proyecto

Gracias a nuestro trabajo de investigación durante más de un año, tenemos la opción de presentar una oferta al 1 Salto tecnológico con software libre Instituto de Fomento de Andalucía para el desarrollo de Properly Software cuenta en la actualidad cuenta con una aplicación para la gestión de entidades y una plantilla de diez personas, de las que la mitad transferencia de tecnología, así como herramientas que

99 Actas del II congreso javaHispano

permitan obtener conclusiones estadísticas de los datos 3 Tecnologías de servidor cruzados. La tecnología J2EE abarca desde JDBC hasta JSP y los Este proyecto consta de cuatro apartados principales: EJBs. Toda esta cantidad de tecnologías está muy bien documentada en la literatura técnica. Nosotros hemos • Gestión de entidades. Consideramos entidades las decidido usar EJBs, SOAP, JAAS, JNDI, JMX y Mbean. empresas, los centros tecnológicos, grupos de Usamos el contenedor de aplicaciones libre JBoss 3.2.x. investigación y organismos. De cada entidad se guarda información sobre su localización, una Hemos tratado de seguir el estandar a traves de sus descripción codificada de su actividad, personas de BluePrints, pero en los escenarios donde JBoss o AXIS contacto, proyectos en los que participan y derechos nos proporcionaba una alternativa más limpia o de propiedad. eficiente, no hemos dudado en hacer uso de ellas. Estos casos pueden resumirse en: • Gestión de documentos de información tecnológica. Aquí se almacenan y clasifican • Consultas dinámicas. El cliente debe poder lanzar documentos en formato XML validados por sus consultas atendiendo a múltiples criterios de respectivos esquemas XML y se transforman a HTML búsqueda. Los mecanismos que proporciona J2EE mediante trasnformadores XLST. (findBy y select) no son lo suficientemente flexible. JBoss propone una alernativa: DinamycQL. Podemos • Herramienta de distribución de información. El construir la sentencia SQL que deseemos a partir de objetivo de ésta es la entrega selectiva de aquellos los datos suministrados por el cliente. documentos tecnológicos a aquellas entidades que lo requieran o que puedan serles de interés. Los medios • Modelo de Seguridad. El modelo basado en roles de envío son el correo electrónico y el fax. no permite expresar restricciones basadas en datos. Poder impedir el acceso de un usuario a las entidades • Gestión de expedientes de patentes y marcas. de una provincia determinada no es expresable con Este apartado está relacionado con las entidades y una política de roles (ni declarativa ni programada). almacena la información relativa a las diversas Diseñamos un evaluador de expresiones (usando actuaciones que se llevan a cabo con las mismas en gramáticas JJTree en JavaCC) que son invocados a relación al patentado o registro de tecnologías. nivel de Beans por los SecurityProxy de JBoss. Estos Del análisis de requerimientos de la plataforma a autorizan (o no) al usuario a retirar este dato. desarrollar determinamos las siguientes necesidades • SOAP por HTTPS. Modificando WSDL4Java y principales: parametrizando los stubs generados por esta • Seguridad: Además de los servicios de seguridad herramienta de AXIS, logramos que el protocolo proporcionados por el sistema operativo (firewall, XML-RCP SOAP viaje por un canal cifrado. cifrado de comunicaciones por SSL) y de la base de • Extensión del modelo de paso de parámetros de datos, nuestra plataforma aporta la posibilidad de configuración. La especificación EJB facilita un definir políticas de particionamiento basadas en los medio de proporcionar valores de configuración datos (seguridad semántica). publicados en el directorio JNDI a las beans, sin • Variedad de clientes: Serán consumidores de los embargo este mecanismo requiere de un redeploy de servicios de la plataforma clientes web y clientes ricos la aplicación ante un cambio de estos valores. Para conectados por Internet con múltiples escenarios de resolver esta problemática, además de otras velocidad de conexión, proxies, firewalls y routers. asociadas al tipo de datos que podemos gestionar, hemos desarrollado un mecanismo mediante una • Extensibilidad: Se prevé la incorporación de nueva MBean que lee los valores de configuración desde un funcionalidad al sistema conforme se produzca la fichero XML. implantación de los servicios existentes.

• Escalabilidad: Se plantea la necesidad de atender solicitudes de clientes en un número creciente y al mismo tiempo se espera un incremento considerable de la información manejada.

100 Actas del II congreso javaHispano

3.1 Seguridad Podemos transformar estas acciones a predicados de la forma expuesta en la Tabla 2. De esta manera un usuario 3.1.1 Requerimientos U puede leer el contenido de un campo F de una entidad E si S(U,E) ^ R(U, F). Un requisito de la aplicación que estamos desarrollando es la de disponer de un mecanismo que permita El predicado S, para poder ser evaluado sobre E necesita controlar las acciones que un usuario puede realizar de un conjunto de cláusulas o expresiones de restricción sobre los datos del sistema. Necesitamos restringir el de U sobre E. Es decir, tenemos que indicar el conjunto acceso de un usuario a un conjunto de campos de un de condiciones que una vez evaluadas nos digan si E bean de entidad y necesitamos limitar el conjunto de pertenece al dominio de este usuario. beans de entidad accesibles por ese usuario. Tabla 2: Predicados La primera restricción acotará las acciones que se pueden Acción Descripción realizar en un campo determinado p.ej: el usuario U puede tener acceso de lectura a un campo pero no lo S(U, E) Entidad E en dominio puede modificar. Este tipo de limitaciones casan R(U, F) Permiso de lectura de F perfectamente con el concepto de seguridad descrita en W(U, F) Permiso de modificación de F la especificación J2EE [1]. En este modelo el usuario tiene X(U, F) Consultar por campo F o no tiene derecho de llamada sobre un método de un bean atendiendo a lo declarado en el fichero descriptor del deploy. Repasados los requerimientos de nuestro sistema de seguridad vemos que necesitamos de: Por contra, limitar el conjunto de beans de entidad sobre los que un usuario debe tener conocimiento no puede 1. Una gramática para expresar restricciones de ser expresado por medio de la seguridad declarativa de dominio.

J2EE. El estándar no nos proporciona ninguna forma de 2. Un evaluador de restricciones. indicar que un usuario concreto, al solicitar la lista de entidades de nuestro sistema mediante la llamada al 3. Una descripción de los metadatos donde podemos método getEntityList() localizado en un SLSB, esta nos poner restricciones semánticas y permisos. devuelva solo aquellas entidades que pertenezcan a una 4. Un lugar estratégico en la arquitectura de nuestro provincia determinada. Es decir, no tenemos la servidor donde determinar los permisos de usuario y capacidad de expresar el dominio de datos de los rechazar o aceptar la solicitudes del mismo. usuarios. 5. Un modelo de datos donde alojar metadatos, En la Tabla 1 podemos ver un resumen de las acciones restricciones y usuarios. que debemos controlar y el receptor de dicha acción.

Tabla 1: Acciones básicas de un usuario

Acción Receptor Acceso (S) Entidad Lectura (R) Dato miembro Escritura (W) Dato miembro Consulta (X) Dato miembro

Las operaciones R,W y X se realizan sobre campos de una entidad. Podemos leer el contenido de un campo, Figura 1: Compilación de las restricciones. modificarlo o lanzar una consulta con este campo como criterio de búsqueda. La operación S determina qué entidades pertenecen al dominio de datos de un usuario.

101 Actas del II congreso javaHispano

3.1.2 Restricciones y Gramáticas valores deben encontrarse en los beans de entidad sobre

Para poder expresar las restricciones de dominio de los cuales estamos imponiendo restricciones. Estas a su manera adecuada hemos diseñado una gramática vez dependen del usuario que realiza la acción. sencilla que sea fácil de evaluar y de convertir a clausulas Vemos pues que necesitamos formalizar y almacenar las WHERE en EJBQL por razones de optimización de las relaciones y los datos (y metadatos) del modelo de consultas. seguridad a través de un modelo de datos. Usaremos

Hemos usado la herramienta JJTree de JavaCC [2] para diagrama Entidad Relación de la Figura 2 para guiarnos. generar árboles AST evaluables mediante un recorrido en postorden del mismo. Realmente el procedimiento de evaluación se ha optimizado traduciendo el árbol AST a una lista evaluable por medio de una pila (Fig. 1).

La gramática propuesta permite expresar restricciones del tipo:

#contato.apellidos LIKE “Delgado%”

#facturacion > #empleados * 1000

Tenemos variables que vienen prefijadas por el símbolo #, operadores, constantes, expresiones regulares, fechas, Figura 2: Diagrama ER de la seguridad. booleanos, números y listas. Es decir, es lo suficientemente completa para expresar un conjunto importante de restricciones.

Para simplificar el uso por parte del administrador encargado de definir estas restricciones de manera dinámica, hemos incorporado la variable sin nombre (#) para indicar 'el campo actual'. De esta manera la expresión (# > 10) AND (# < 100) tiene un significado diferente si se aplica al campo 'número de empleados' o 'edad'.

Con JJTree definimos los tokens que deberá encontrar el analizador lexicográfico, la gramática que el parser descendiente recursivo de JavaCC reconocerá, y las reglas Figura 3: Arquitectura general del sistema. de creación del árbol AST. Especificar una gramática en

JavaCC es sencillo siempre que mantengamos en mente algunas reglas sencillas como la de ir definiendo las Hay restricciones sobre una entidad y sobre campos de la reglas de producción en orden inverso a la precedencia entidad. Necesitamos recopilar en el sistema toda la de los operadores. Es decir, debemos indicar primero las información que tengamos sobre los objetos susceptibles reglas de producción que tienen operadores de más baja de ser controlados. Hemos denominado a dichos objetos precedencia. del sistema, PDO (Persistent Data Object, Objetos de Datos Persistentes). Cada PDO tiene un conjunto de Recorrido el árbol en postorden (subárbol izquierdo - campos. Así por ejemplo, el PDO de un Contacto tiene subárbol derecho – raíz), y puesto los nodos del árbol de los campos Nombre, Dirección y Teléfono sobre los que manera lineal, la tarea del evaluador queda simplificada. podremos poner restricciones y permisos.

3.1.3 Modelo de datos Estos metadatos pueden generarse automáticamente usando herramientas como XDoclet [3] o bien Disponemos ya de una herramienta para evaluar introducidos en el sistema de manera manual. Por restricciones. Para realizar su tarea el evaluador necesita desgracia generan una evidente redundancia, puesto de los valores de las variables de su expresión. Estos

102 Actas del II congreso javaHispano

que los datos securizables son los mismos que tenemos está en que la seguridad quedaría difuminada y en los Beans de Entidad (CMP y BMP), que a su vez repartida en cada uno de los métodos de esta capa. La tienen una contrapartida en el modelo de datos global dificultad en el mantenimiento e implementación sería de la aplicación. desaconsejable. Si bien tenemos a nuestra disposición patrones de diseño como los Decorators y los Proxy que Necesitamos almacenar los datos de los usuarios (login, pueden ayudarnos, quizás hay una alternativa mejor. nombre, contraseña...) para poder activar el mecanismo de autentificación y autorización de J2EE. Cada usuario Si lográramos poner la seguridad en la capa de pertenece a un grupo de usuarios y este a su vez dispone persistencia, donde encontramos lo BMPs y CMPs de de varios roles dentro del sistema. nuestro sistema, la seguridad sería óptima. Ningún acceso a los datos (excepto claro está, accediendo Almacenamos los datos correspondiente a los permisos directamente a la base de datos) podría saltarse las de lectura, escritura y consulta de los campos y las comprobaciones de seguridad, y la situaríamos al mismo restricciones que determinan el dominio de datos de un nivel que la seguridad nativa de J2EE, mano a mano y usuario. complementándose. Los permisos se relacionan con un grupo de usuarios y Para lograr este nivel de integración necesitaremos echar los campos de los PDOs. Por tanto para cada mano de los interceptores. Aquí AOP nos puede ayudar, grupo/campo indicamos los permisos R,W,X. pero decidimos, puesto que usamos JBoss 3.2.x, acceder Las restricciones de dominio asocian el grupo de usuario a las facilidades en la arquitectura de interceptores que con el conjunto de restricciones sobre un PDO en nos brinda este contenedor J2EE de código libre. concreto. Ahora tenemos una estructura donde Los SecurityProxy [4] son unos interceptores a nivel de recuperar la lista de restricciones que tenemos que beans que permiten separar la seguridad del resto de los evaluar para saber si un usuario del sistema tiene o no procedimientos. Este tipo de proxy es llamado antes de tiene permiso de acceder a un Bean de Entidad en cada invocación a los métodos del bean, es por tanto concreto. una gran oportunidad para abortar esta llamada en caso de que no se cumplan las restricciones de seguridad de 3.1.4 JBoss y los SecurityProxy nuestro sistema. Hay dos tipos de SecurityProxy, uno que Llegados a este punto disponemos de un evaluador de tiene dos métodos (uno que se ejecuta para cada restricciones y de un sistema que nos devuelve la lista de llamada a los métodos Home (create, findBy y selects) y restricciones a evaluar cuando un usuario quiere acceder otro para los métodos del objeto (postCreate, set, get y a una entidad. La cuestión ahora es en qué lugar de la remove)) y otro tiene el mismo interfaz que el CMP o arquitectura de nuestro sistema sería más conveniente BMP que estamos interceptando. realizar estas evaluaciones para aceptar o denegar la Este modelo tiene la venta de poder navegar por las acción. relaciones de manera natural. Podemos establecer una La Figura 3 es una sobresimplificación de la arquitectura restricción sobre un elemento relacionado con el que del sistema. Vemos tres oportunidades donde colocar entramos tratando. Así puedo decir, por ejemplo, que un nuestro mecanismo de seguridad. usuario del sistema no puede acceder a las empresas que tenga al menos un cliente de nombre Raul. Restricciones Si lo colocamos en la capa más externa de todas, la capa así demuestran la potencia del planteamiento del SOAP, por cada petición de un usuario, el sistema de modelo, si bien presenta un problema: demasiadas seguridad deberá atravesar toda la arquitectura para intercepciones pueden penalizar el rendimiento. recuperar los permisos, las restricciones y los datos necesarios para evaluar dichas restricciones. Es evidente 3.1.5 Optimizando el modelo que es poco óptimo y complejo. Además estamos incorporando lógica en la capa de comunicaciones. Si disponemos de un conjunto de restricciones expresadas en un lenguaje similar al EJBQL, al menos en Incorporar la seguridad semántica dentro de la Session lo que respecta a la cláusula WHERE ¿por qué no Façade es factible. Estamos completamente dentro del construir una expresión que aplicada a cualquier servidor, dentro del segmento de nuestra aplicación donde recaen las decisiones de negocio. El problema

103 Actas del II congreso javaHispano

consulta del sistema nos traiga el subconjunto de datos 4.2 Hylafax accesibles por el usuario? Hylafax es un servidor para el envío y recepción de faxes, De esta manera limitamos el númer de excepciones de código libre y amplio uso. Acepta peticiones de asegurando siempre la corrección del modelo. Aun sin transmisión vía sockets mediante un protocolo derivado esta optimización el sistema impide desde su base el de FTP. Para facilitar la comunicación de nuestra acceso a los datos no autorizados. aplicación Java con Hylafax existen librerías también de código libre. Nuestra interacción con el servidor Hylafax Esta optimización hay que entenderla como tal: es la se reduce a dos puntos muy concretos: el envío de faxes única separación del modelo de seguridad, ya que hasta y la determinación de si han sido enviados ahora todo el asunto estaba localizado en los correctamente. interceptores. Utilizamos HTML2PS para la transformación de nuestros documentos HTML (generados a partir de los 4 Tecnologías auxiliares documentos de información tecnológica mediante Además de las tecnologías que nos proporciona J2EE, transformadores XSLT) en documentos PostScript. hemos necesitado usar otras herramientas para cumplir Para la comprobación del estado de los envíos usamos con las especificaciones de la plataforma desarrollada. una técnica de polling a intervalos regulares de tiempo. Esta tarea la hemos llevado a cabo mediante el mecanismo de integración por Mbeans proporcionado por JBoss. Los casos en los que ha sido necesaria esta 5 Tecnologías de cliente integración son: Inicialmente consideramos dos alternativas como framework para la creación de nuestra aplicación de 4.1 Lucene escritorio. Una era NetBeans Platform, que permite la construcción de aplicaciones Java con componentes El modelo de datos de Lucene gira alrededor del Swing. Descartamos esta solución debido a cuestiones concepto de documento: un conjunto estático de de rendimiento, consumo de memoria y aspecto general. campos de texto (accesibles por nombre), que constituye la unidad de indexación. En la compilación del índice se La otra alternativa, y la elegida, era Eclipse. Se basa en el le añaden documentos y en la búsqueda por palabras se uso de componentes nativos del sistema operativo obtienen los documentos que satisfacen las condiciones cuando estos están disponibles (SWT) y un modelo muy de las consultas. sencillo de datos para los componentes JFace.

Bajo esta funcionalidad de alto nivel hay un sofisticado sistema cuyo conocimiento resulta fundamental cuando 5.1 Eclipse Rich Client Platform se requiere (como en nuestro caso) modificar el sistema Con RCP disponemos de todo un framework para la en cierto grado para adaptarlo a nuestras necesidades. escritura de aplicaciones de escritorio. Con el término En este sentido, ha resultado fundamental la posibilidad Rich Client Platform, la comunidad Eclipse se refiere al de consultar el código fuente para poder comprender mínimo conjunto de plugins que son necesarios para Lucene de un modo más completo. construir una aplicación con un interfaz de usuario. Este Para el sistema de notificación de modificaciones en los conjunto mínimo de plugins se reduce a tan solo dos: documentos indexados se dispone de un acceso a la org.eclipse.ui y org.eclipse.core runtime, sin embargo capa de persistencia usando el patrón de diseño Session podemos usar el resto del API ofrecida por Eclipse. façade. Aprovechamos la característica de proxys de JBoss para interceptar las llamadas de actualización a los 5.2 SWT (Standard Widget Toolkit) beans. Este enfoque sugiere una aproximación a la SWT es una librería para crear interfaces de usuario en programación orientada a aspectos. Java. Se caracteriza por su integración con los componentes gráficos del sistema operativo sobre el que corre, lo que supone una apariencia unificada con el resto de programas de esa plataforma y una velocidad de ejecución nativa. Como contrapartida, se plantean

104 Actas del II congreso javaHispano

problemas a la hora de hacer portable el código, aunque ha permitido ser capaces de ofrecer un tipo de ha sido solucionado bastante elegantemente. La manera soluciones al nivel de empresas de mucha más de acceder a los elementos gráficos del sistema embergadura y con un presupuesto muchísimo mayor. operativo se resuelve usando JNI (Java Native Interface), Si hubiésemos pretendido implementar todo nuestro accediendo a una serie de métodos escritos en C, que desarrollo con software propietario, el coste hubiese son los que realmente acceden a los recursos del sistema superado con creces nuestras posibilidades si sumamos operativo. Por tanto, es necesario tener en cuenta dos sistema operativo, gestor de bases de datos, servidor de aspectos: la elección de las funciones que se proveerán aplicaciones, servidor de fax, entorno de desarrollo, etc. en la primera capa implementada en C, de manera que Por el contrario, siempre hemos encontrado una hagan una abstracción genérica de las diferentes alternativa libre con unas prestaciones en ocasiones plataformas (Windows, Motif, MacOs, etc…). Esta capa superiores a las ofrecidas por la alternativa propietaria. debe ser tan delgada como sea posible para asegurar eficiencia y que todo el código del manejo de widgets esté implementado en Java. El segundo es aportar una 6.2 Consideraciones técnicas implementación diferente para cada plataforma, Disponer del código fuente de las herramientas usadas generando una librería dinámica para cada una de ellas, ha sido, en determinados casos, decisivo para el éxito de la cual será importada en tiempo de ejecución por la nuestro proyecto. En ocasiones en las que no librería de SWT mediante System.loadLibrary(). comprendíamos una determinada tecnología, la inmersión en el código fuente nos ha facilitado la 5.3 JFace información que no encontrábamos en la documentación, además de corregir errores (tratamiento JFace es una librería para simplificar las tareas comunes de las conexiones HTTPS en Axis) y extender su de la programación de interfaces de usuario. Está escrita funcionalidad (modelo de documentos de Lucene, uso sobre SWT, pero no lo sustituye. de certificados digitales de la SDK de IBM en JBoss). Las utilidades que suministra están clasificadas como En nuestro desarrollo hemos empleado herramientas que sigue: nos permiten asegurar características avanzadas en • Viewers: manejan las pesadas tareas de rellenar, rendimiento, seguridad, escalabilidad y fiabilidad. ordenar, filtrar y actualizar los widgets. Ejemplos son el SGBD PostgreSQL 7.4, el servidor de aplicaciones J2EE certificado en su versión 4.0 JBoss, el • Acciones y Contribuciones: incorporan una sistema operativo GNU/Linux o el contenedor de semántica para definir acciones de usuario. aplicaciones web Tomcat 5.0. • Imágenes y fuentes: patrones de manejo de recursos de interfaces de usuario. 6.3 Coste del aprendizaje

• Diálogos y wizards: estructuras para definir La desventaja del software libre radica en que, interacciones complejas con el usuario. generalmente, la documentación existente no suele ser muy abundante o estar muy actualizada. Esto es debido 6 Conclusiones principalmente a que los esfuerzos de la comunidad de desarrolladores se centran en la evolución del propio 6.1 Consideraciones económicas código y no en facilitar la transmisión de esa información. Como ejemplo de muy mala Debido al tamaño de nuestra empresa y a los limitados documentación nombraremos el servidor Hylafax y el API recursos económicos disponibles para tareas de Java para su manejo, que prácticamente carecía de ella y investigación, el uso de software libre ha supuesto un nos obligó a estudiar su código fuente para descubrir su hito definitivo en nuestro salto tecnológico. Es de modo de funcionamiento. Por el contrario, el entorno de resaltar que partíamos de una filosofía de programación desarrollo Eclipse tiene una muy buena y abundante procedural, dependientes por completo de una solución documentación. cerrada, sin posibilidades de crecimiento, desarrollada y soportada por una única empresa. El software libre nos El coste de aprendizaje, por tanto, es elevado pero se ve compensado por el gran ahorro de costes en licencias.

105 Actas del II congreso javaHispano

Referencias

[1] Sun Microsystems, Inc. J2EE Patfrom Specification. http://java.sun.com/j2ee/j2ee-1_4-fr-spec.pdf [2] Java Compiler Compiler. https://javacc.dev.java.net/ [3] XDoclet. http://xdoclet.sourceforge.net [4] Customized EJB security in JBoss. JavaWorld 15/02/2002 http://www.javaworld.com/javaworld/jw-02-2002/jw-0215- ejbsecurity.html

106 Actas del II congreso javaHispano

Integración Continua utilizando herramientas Open Source

Jesús Pérez Sánchez www.agile-spain.com / Germinus [email protected]

los problemas de las metodologías tradicionales. Abstract Problemas de adaptación a los entornos actuales de

En un entorno en el que el sector de servicios se ha vuelto proyectos, que se caracterizan por requisitos variables, mucho más complejo, ser eficientes se convierte en una plazos breves así como presupuestos y recursos exigencia para poder sobrevivir en este mercado. La ajustados. Las metodologías ágiles introducen cambios experiencia en el desarrollo de software a medida nos dice importantes sobre los modelos existentes de ingeniería que es habitual emplear mucho tiempo en integrar el del software, apoyándose en la experiencia de prácticas trabajo realizado por todo el equipo de desarrollo y, sobre aplicadas con éxito, que en muchos casos no resultan todo, en llevar este desarrollo del entorno de desarrollo a novedosas. producción. La integración continua es una de las prácticas que

La integración continua es un proceso que permite propone XP (eXtreme Programming []), una de las comprobar continuamente que todos los cambios que lleva metodologías ágiles más conocidas. Se trata de una cada uno de los desarrolladores no producen problemas de práctica que organiza el trabajo de integración a lo largo integración con el código del resto del equipo. Los entornos de todo el proyecto. Implantar esta práctica supone un de integración continua construyen el software desde el cambio más dramático de lo que en principio parece, repositorio de fuentes y lo despliegan en un entorno de dado que implica una nueva forma de entender el integración sobre el que realizar pruebas unitarias o de desarrollo. aceptación. La integración continua es también un buen ejemplo de

Implantar procesos de este tipo conlleva una inversión en una regla básica de un programador pragmático []: tiempo que será recuperada conforme avance el proyecto. “Intentar automatizar todo el trabajo repetitivo que No obstante, esta inversión es cada vez más reducida realiza”. gracias a la disponibilidad de herramientas Open Source que nos ofrecen soluciones de Integración Continua cada 2 Integración Continua vez más sencillas de implantar. Herramientas como ¿Cuántas veces hemos oído a un desarrollador decir que CruiseControl combinadas con Ant, Maven, Junit o DBUnit, el código que ha desarrollado “funciona correctamente nos ofrecen la posibilidad de implantar un proceso de en su máquina”? Ésta es la respuesta estándar cuando Integración Continua pudiendo utilizar en este proceso un problema de integración ha sucedido. otras técnicas como la gestión de la configuración o generación de informes de forma automática. Integración continua consiste en disponer de un proceso automatizado que permita la construcción de nuestro Palabras clave: Metodologías Ágiles, XP, Integración software desde las fuentes, que despliegue nuestro Continua, Herramientas Open Source, Agile-Spain, software en un entorno similar al entorno final y que

lleve a cabo el conjunto de pruebas que validan su 1 Metodologías ágiles correcto funcionamiento. Si nuestro sistema pasa correctamente las pruebas podemos completar el Las metodologías ágiles han aparecido dentro del marco proceso desplegando nuestro software sobre un entorno de la Ingeniería del Software como una respuesta ante

107 Actas del II congreso javaHispano

donde pueda estar disponible. Este proceso debe poder las prácticas más complicadas a nivel técnico de aplicar realizarse muchas veces al día. de las que nos proponen XP.

El concepto que hay detrás de integración continua Estos beneficios son los siguientes: (Continuous Integration o CI) es que se debe integrar el • Minimiza las sesiones de búsqueda de fallos a la desarrollo de una forma incremental y continua. Esto hora de integrar el código. Fallos realmente permite encontrar problemas de integración y resolver complicados de encontrar dado que suelen ser este tipo de problemas durante el desarrollo. efectos colaterales de código que ha sido Integración continua es el término que se utiliza para dar desarrollado de manera independiente. nombre a esta práctica dentro de la metodología de XP. • Permite identificar fallos en el entorno de No obstante es una práctica que no es nueva y que es producción en etapas tempranas. Esto permite aplicada en todo tipo de entornos de desarrollo de ser eficiente en los pasos a producción y evitar software. los periodos de integración finales en los Para conseguir automatizar este proceso de entornos de producción. construcción, pruebas y despliegue de manera que se • Minimización del tiempo de realimentación con realice diariamente muchas veces es necesario también: el cliente, al minimizar el paso de desarrollo a • Almacenar las fuentes en un único lugar del que un entorno de integración. pueda obtenerse la última versión del proyecto • Eficiencia del equipo de desarrollo: no es (y versiones anteriores). necesario todo el conjunto de pruebas en el • Automatizar el proceso de construcción de entorno local, minimiza el tiempo de paso a manera que se pueda, con un único comando, producción. construir todo el sistema a partir de las fuentes • Aumenta la confianza en el cdigo subido al • Automatizar las pruebas de forma que sea control de versiones. posible y de forma automática, saber si todo está bien o hay algún problema. 4 Plataforma Open-Source

Introducir integración continua en un proyecto no suele Implantar Integración Continua es una tarea de una resultar sencillo. En muchos casos es realmente cierta complejidad técnica. Automatizar todo el proceso complicado automatizar el conjunto de tareas repetitivas que hemos descrito anteriormente sin apoyarnos en que debemos realizar para conseguir una versión de ninguna herramienta resultaría bastante costoso. nuestro software. Es muy habitual que no existan pruebas automatizadas asociadas al proyecto, lo que En la actualidad no es necesario desarrollar implicará un esfuerzo considerable conseguir dotar a herramientas propias que permitan esta automatización nuestro software de este conjunto de pruebas. A pesar desde cero, dado que existen ya una serie de frameworks de todo, el mayor esfuerzo que podíamos encontrar, el que ofrecen soporte para esta práctica. Podemos desarrollo de la plataforma de integración, no es encontrar herramientas comerciales y herramientas necesario realizarlo en la actualidad gracias a la aparición Open-Source. de plataformas abiertas de integración continua. El movimiento de Open-Source se ha consolidado en la actualidad como un punto de referencia para cualquier 3 Beneficios de la Integración Continua desarrollo. El extenso conjunto de herramientas, la calidad y el espectacular avance que se puede observar Introducir integración continua supone generalmente en muchos de los proyectos ha hecho que, hoy en día, para una organización, un cambio sustancial en su forma muchos de estos desarrollos se hayan convertido en de desarrollar software. Es una práctica que requiere estándares (Struts, Ant, etc..). Resulta una ventaja introducir cierta disciplina dentro del grupo de desarrollo competitiva la utilización de estas soluciones en lugar de de software, que se verá compensada generalmente con tratar de desarrollar soluciones similares pero una mejora de la eficiencia. Probablemente sea una de propietarias. Es complicado que soluciones propietarias puedan competir en funcionalidad con las soluciones

108 Actas del II congreso javaHispano

libres cuyo coste de desarrollo es cero. Unas soluciones nuestro software que hayamos generado hace tiempo cuya funcionalidad esta en continua evolución y que nos siempre para construir el software únicamente nos permitirán evolucionar tecnológicamente con ellas. hayamos apoyado en las fuentes que existían el control de versiones. Para Integración continua podemos encontrar diferentes soluciones tanto Comerciales como Open-Source: Introducir el control de versiones en un equipo es una práctica que supone un cambio sustancial en la forma de • CruiseControl (Open-Source) trabajar de un equipo. A partir de ahora nuestro trabajo • AntHill(Comercial/Open-Source) se compartirá con nuestros compañeros diariamente, lo que nos impondrá ciertas buenas practicas que • DamageControl permitirán que todos podamos trabajar eficientemente. El más extendido de estos frameworks de integración es Será importante ser cuidadoso con el código que Cruise-Control que ha sido desarrollado por una de las introducimos en el control de versiones para evitar que empresas más importantes dentro del movimiento ágil, nuestros compañeros al actualizarse tengan problemas ThoughtWorks, por lo que supone probablemente la para seguir desarrollando. mejor forma de introducirse en esta práctica. La experiencia al final nos hace ver que lo necesitaremos incluso cuando realicemos desarrollos individuales y en 4.1 CruiseControl los que tengamos una única entrega, dado que es fácil Cruisecontrol es un framework que nos va a permitir descubrir que es una herramienta muy potente para implementar dentro de nuestro proyecto un proceso de desarrollar (permite poder identificar los cambios que se integración continua. Este framework se apoya en otras hicieron en las fuentes desde una fecha determinada, herramientas que se describen a continuación evita la proliferación de copias de seguridad de nuestro código, identifica claramente cuál es la ultima versión, etc…). 4.1.1 Control de Versiones

Para poder implantar una herramienta de integración 4.1.2 Pruebas Automatizadas continua la primera condición es tener un repositorio con todas las fuentes del proyecto. Existen diferentes El siguiente paso para poder llegar a implantar repositorios de control de versiones como CVS, Integración Continua es el desarrollo de pruebas Subversión, ClearCase, VisualSourceSafe, etc. Cada uno automatizadas. de estos repositorios tiene características diferentes que Implantar esta práctica es uno de los retos más difíciles tendremos que evaluar cuando decidamos implantarlo que nos encontraremos en la implantación de la en nuestro proyecto. Uno de los mas implantados y que integración continua. es utilizado en la mayoría de los proyecto de Open Source es CVS. No obstante y en los últimos tiempos, Desarrollar un conjunto de pruebas completas de parece que está siendo desplazada por Subversión que nuestro sistema es una tarea cuya complejidad ofrece unas funcionalidades para trabajar con diferentes dependerá del entorno de ejecución de nuestra ramas de trabajo mucho mas potentes. aplicación y de las interacciones con sistemas externos. Un conjunto de pruebas completas de nuestro sistema Utilizar Control de Versiones es una práctica se hace implicaría tener diferentes conjuntos de pruebas: especialmente imprescindible cuando se trabaja en entornos colaborativos y en los que se desarrolla de una • Pruebas Unitarias forma evolutiva para que el software pueda estar • Pruebas de Rendimiento disponible desde las primeras versiones. Estas dos razones han hecho de estos sistemas el corazón de los • Pruebas de Integración con sistemas externos proyecto de Software Libre. • Pruebas de Diseño (Accesibilidad)

El control de versiones contiene toda la historia de los • Pruebas Funcionales cambios que se han ido produciendo en nuestro código. Éste nos permitirá replicar cualquier momento de En el modelo tradicional de desarrollo este tipo de nuestro desarrollo y por tanto generar cualquier de pruebas se realizaban una vez finalizado el desarrollo. No

109 Actas del II congreso javaHispano

obstante este enfoque no suele funcionar en la mayoría • StrutsTestCase: Extensión para hacer pruebas de los proyectos de desarrollo y es realmente poco unitarias sobre actions de struts efectivo. • DBUnit: Suite para pruebas muy dependientes Desarrollar pruebas automáticas nos permite comprobar de los datos almacenados en Bases de Datos en cualquier momento y ejecutando la ‘suite’ de pruebas • HttpUnit, JUnit, CanooWebTest: Pruebas si nuestro sistema cumple con la funcionalidad directamente contra la aplicación web implementada hasta el momento. Esta facilidad es tremendamente útil durante el desarrollo, puesto que Realizar pruebas puede ser complicado pero siempre es nos permitirá desarrollar cambios con seguridad, sin posible. Incluso en entornos muy específicos en los que tener que pagar el esfuerzo de volver a probar todo. no encontremos suites que simulen el comportamiento Dejar las pruebas para el final del desarrollo nos privará de los elementos externos, es posible desarrollarnos de esta ventaja. mediante Mock-Objects clase que simulen estos comportamientos. En muchos casos este tipo de pruebas La herramienta más extendida y la que cuenta con una nos servirán no solamente para comprobar que nuestras comunidad más activa para el desarrollo de pruebas es clases funcionan correctamente, si no para acelerar JUnit. JUnit nos ofrece un framework sobre el que nuestro desarrollo, al no tener la necesidad de realizar desarrollar las pruebas de nuestro sistema de una forma las pruebas sobre esos entornos. homogénea, que nos permitirá que nuestro conjunto de pruebas crezca de una forma ordenada. Este framework se acompaña de un conjunto de utilidades que permitirá 4.1.3 Automatización (Scripting) presentar los resultados en diferentes formatos (XML, Una vez llegados a este punto nos encontramos en HTML). Una de las características más importantes de situación de poder comenzar a pensar en automatizar esta plataforma es que nos ofrece la posibilidad de todas las tareas que realizamos, para conseguir construir ejecutar todo el conjunto de pruebas ejecutando un nuestro sistema a partir del código que hemos único comando y que se integra perfectamente con desarrollado y lograr que sea desplegado y este lenguajes de scripting como es Ant. disponible para poder ser utilizado.

Esta combinación es muy potente dado que podremos Una de las claves de la eficiencia en el desarrollo es el incorporar de manera automática las pruebas de nuestro nivel de automatización que hemos conseguido software al proceso en el que se construye una nueva implantar en todas las tareas relacionadas con el versión. De esta manera podremos asegurar, cuando desarrollo. creemos una nueva versión de nuestro software o cuando lo despleguemos sobre un entorno, que el Pero aún siendo la mejora de la eficiencia una excelente código pasó previamente las pruebas que certifican el razón para decidir comenzar a automatizar los procesos funcionamiento correcto de todas las funcionalidades. de nuestro desarrollo hay otra razón que muchas veces queda oculta y que es en mi opinión mucho más Sobre JUnit se han desarrollado muchas extensiones importante: la capacidad de poder repetir los procesos realmente útiles que ofrecen librerías para facilitar cierto de una manera exacta. El desarrollo de software es una tipo de pruebas. Especialmente interesante son las disciplina con un alto grado de incertidumbre. Al gran librerias de: número de variables que afectan a un desarrollo • JUnitPerf: Introducir pruebas de rendimiento (Sistemas Operativos, Base de Datos, Integración con durante el desarrollo es muy sencillo y muy sistemas externos, Servidores de aplicaciones) en muchas valioso, especialmente en aquellas clases criticas ocasiones añadimos nosotros todavía más incertidumbre como las de acceso a Basede Datos, las que al introducir procesos manuales al proceso de realicen operaciones pesadas (algoritmos, construcción del software. parseo de XML, integración con otros sistemas Conseguir que nuestro proceso de despliegue sea externos, etc..) idéntico en todas las ocasiones nos asegurará poder • Cactus: Para permitir pruebas realizadas replicar o repetir cualquier proceso previo que hubiera directamente sobre el contenedor. Pruebas sido exitoso. unitarias sobre el entorno final

110 Actas del II congreso javaHispano

Pero automatizar un proceso puede ser una tarea que entorno real a escala reducida. Dependiendo de los conlleve mucho esfuerzo. Entonces la pregunta es ¿Qué sistemas involucrados con el software que se desarrolla debemos automatizar?. En nuestra opinión cualquier en algunos casos se compartirá alguno de estos sistemas proceso manual que vayamos a realizar en más de una en lugar de instalarlos en el entorno local. También es ocasión. posible solucionar este problema utilizando clases que en lugar de utilizar los servicios remotos, simulen este Para automatizar todos estos procesos Java cuenta con comportamiento. una herramienta ANT que nos permite llevar a cabo la mayoría de las tareas que realizamos de forma manual con una consola. Tareas como copiar ficheros, compilar nuestras clases, hacer FTP a otras máquinas con versiones de nuestro software, ejecutar nuestras pruebas, pueden ser automatizadas con ANT.

ANT es un framework para realizar scripts a partir de una serie de tareas predefinidas. Este framework es muy extensible y permite introducir nuevas tareas si fueran necesario. Aunque la extensa contribución de la comunidad de ANT hace que sea complicado encontrar tareas que no estén implementadas dentro de ANT.

El problema con Ant reside en que las tareas que ofrece son de muy bajo nivel y deberemos invertir en tiempo en automatizar nuestras tareas mas comunes de desarrollo Para resolver este problema ha surgido Maven que nos Cada desarrollador subirá periódicamente sus nuevos ofrece una posible implementación de todas estas tareas desarrollos al entorno de control de versiones e irá de alto nivel. (preguntar a Dani) actualizándose con las modificaciones que vayan realizando otros miembros del equipo.

4.1.3 Configuración de CruiseControl El entorno de integración continua (en nuestro caso Hay diferentes formas de abordar un proyecto de CruiseControl) suele estar instalado en el entorno de desarrollo. Nos encontramos desde proyectos en los que integración. Esto permite que podamos desplegar de todo el equipo desarrolla en misma máquina, hasta una manera sencilla el software sobre el entorno de proyectos en los que cada desarrollador tiene asignado integración una vez que ha pasado las pruebas. su ordenador personal y una máquina adicional similar al Para instalar CruiseControl es necesario tener en cuenta entorno de desarrollo. También nos encontramos los siguientes directorios empresas que tiene un servicio de control de versiones general para todos los proyectos y otras en las que cada proyecto es responsable de su repositorio de control de versiones.

Para detallar el proceso de integración continua y la configuración de CruiseControl supondremos un entorno en el que cada usuario desarrollar en su entorno local, que existe una maquina dedicada al control de versiones y que existen dos entornos comunes integración y En estos directorios se instalar producción. • CruiseControl: En este directorio instalaremos la herramienta de integración continua.

Cada desarrollador dispondrá de un entorno local en el • Tomcat: Tenemos la opción de publicar los cual realizará la mayor parte del trabajo de desarrollo. En resultados mediante una aplicación web. Esto este entorno dispondrá de un entorno simulado del

111 Actas del II congreso javaHispano

nos obligará a instalar un contenedor de La Integración continua es una práctica de la que todo el servlets como Tomcat mundo ha oído hablar pero que muy pocos equipos de desarrollo aplican (incluyendo aquellos que utilizan • Fuentes del Proyecto: Este directorio lo metodologías ágiles como XP) utilizaremos para que CruiseControl tenga su copia del código del control de versiones. ¿A que se debe que no este nada extendida?.

CruiseControl no tiene una arquitectura muy sofisticada, consta de un proceso que cada cierto tiempo 5.1 Problemas implantando Integración comprobará una serie de condiciones para lanzar una Continua serie de acciones. El principal problema que nos hemos encontrado al

La otra parte de la arquitectura es la herramienta de aplicarla es que en la mayoría de los casos supone la publicación de la actividad de este proceso. Esta introducción de otras prácticas en las que se apoya. herramienta esta desarrollada en Java y esta • Control de Versiones: Necesitamos tener control empaquetada en un war. Instalando un Tomcat y de versiones de nuestro código, de manera que desplegando esta aplicación configurada correctamente podamos recuperar cualquier versión del tendremos disponibles via web la información de la proyecto. Esta es una practica muy extendida y actividad del proceso principal de CruiseControl no suele suponer un problema.

Toda la configuración de CruiseControl esta centralizada • Pruebas Automáticas: La integración continua en un único fichero. En este fichero podremos configurar pierde gran parte de su valor si no existen. todas las propiedades del proceso de integración Implantar esta práctica una vez comenzado el continua. Las más importantes son: proyecto es muy costoso y supone una parada

• ModificationSet: En este propiedad se especifica del desarrollo. Incluir pruebas automatizadas al a CruiseControl cuales son las condiciones que proyecto y programar desarrollando pruebas es se tiene que producir para lanzar un proceso de uno de los cambios de filosofía necesario si construcción, despliegue y pruebas del queremos implantar Integración Continua Software. Generalmente lo asociaremos a • Construcción y despliegue automatizados: Esta cambios en nuestro control de Versiones es una de las tareas que tendremos que realizar

• Schedule: En esta propiedad especificaremos si no existen los scripts que permitan llevar a cada cuanto tiempo el control de versiones cabo este proceso sin intervención manual. deberá realizar un build como máximo si no se produce alguna condición que lo lance. En esta 5.2 Buenas Prácticas propiedad se detalla exactamente el script de La integración continua impone un desarrollo en equipo Ant y el objetivo que deberá lanzar más disciplinado. En muchos proyectos no se es CruiseControl que es el que automatiza todo el consciente de que se trabaja en equipo hasta que llega el proceso de construcción, despliegue y pruebas. momento de la integración final. • Publisher: En esta propiedad especificamos La integración continua hace que nuestro desarrollo sea como notificaremos de los resultados de prueba incremental. En cada momento nuestro sistema ofrecerá al equipo de desarrollo. una serie de funcionalidades que serán las que prueben nuestro conjunto de pruebas automáticas. Los nuevos 5 Experiencia Real desarrollos añadirán nuevas funcionalidades evitando La experiencia real aplicando integración continua que las anteriores dejen de funcionar. Cuando el demuestra que aplicar esta práctica supone una pequeña conjunto de funcionalidades de nuestro sistema ofrezca revolución en la forma de desarrollar. Implica un cambio la posibilidad de tener un software coherente con nuevas de filosofía para el que es necesario un periodo de posibilidades, entonces en ese caso deberemos crear una adaptación. nueva versión.

112 Actas del II congreso javaHispano

Para que este desarrollo incremental funcione • Coordinar aquellos cambios o correctamente la experiencia nos dice que es necesario reestructuraciones que influyan en gran parte seguir las siguientes prácticas: del código: La integración continua implica un elevado grado de coordinación. Estas • Desarrollar pruebas a medida que se desarrollan coordinaciones son especialmente importantes funcionalidades: Cada nueva funcionalidad que en aquellas modificaciones que vayan a afectar se integre en el control de Versiones deberá a muchos módulos. En estos casos muchas tener su conjunto de pruebas. Cuando se veces es más eficiente hacer este tipo de modifique alguna funcionalidad también será cambios desde situaciones estables, para necesario modificar su conjunto de pruebas. intentar evitar efectos colaterales. Es posible Utilizar desarrollo dirigido por pruebas TDD que estos cambios sean realizados por cada facilita esta tarea. programador en los módulos en los que esta • Política de Semáforos: Una vez que utilicemos trabajando. integración continua el sistema nos informara • Responsable del entorno de integración del estado del software De esta manera continua: Nuestra experiencia aplicando recibiremos continuamente notificaciones Integración Continua es que es muy cuando el código que tengamos en nuestro conveniente tener un responsable encargado de repositorio de versiones no pase las pruebas. En que este entorno funcione correctamente y de ese caso tendremos el semáforo en rojo para que el equipo esta siguiendo las reglas subir nuevo código al CVS. Esto nos permitirá anteriores. Esta persona será la responsable de no introducir nuevas clases antes de identificar arreglar aquellos errores que surgen sin que se cuales han sido las clases responsables de este haya realizado ningún cambio por el entorno en problema. Si el control de versiones nos ha el que se ejecutan los test. enviado un mail avisándonos del éxito de nuestras pruebas, entonces en ese momento el • Los mails que genera el Control de Versiones no semáforo estar verde para subir nuevo código son Spam: Nuestra experiencia nos dice que hay estará en Verde. ciertos periodos en los que se produce cierta inestabilidad en el entorno de control de • Tiempo máximo de solución de errores en el versiones. En esos momentos es cuando al control de Versiones: En la medida de lo posible recibir muchos emails de sistema de integración tenemos que minimizar el tiempo en que el continua nos sentimos tentado de tratar este desarrollo que hay en el control de versiones no como Spam (redirigiendolo a la carpeta de pasa las pruebas. En aquellos casos en los que borrar o a otra carpeta que no consultaremos). sea difícil arreglar un problema que hemos Estas situaciones tenemos que tratar de detectado una vez subido el código al control evitarlas tratando de solucionar el problema de de versiones la mejor opción es volver al código la inestabilidad lo antes posible e de la versión anterior. interrumpiendo temporalmente el envió de • Minimizar el tiempo entre integraciones: Uno correos. Los correos nuestro sistema de de los objetivos principales de la integración integración continua debemos tratar de continua es realizar continuamente atenderlo lo antes posible para conseguir todos integraciones, cuanto mas a menudo se realicen lo beneficios de implantar esta práctica. mejor funcionara el proceso. Por este motivo • Conseguir que nuestras pruebas, prueben el hay que intentar que este tiempo sea el mínimo sistema y sean fáciles de mantener Es posible. Por este motivo tenemos que conseguir importante que nuestras pruebas nos ayuden a mantener nuestro proceso automático lo mas conocer que nuestro sistema funciona. En rápido posible, tratando de reducir el tiempo muchos casos desarrollamos conjuntos de que consumen las pruebas y el tiempo que pruebas que nos dan muy poca información consume el despliegue. sobre las funcionalidades de nuestro sistema y con un gran coste de mantenimiento. No

113 Actas del II congreso javaHispano

conseguir este propósito nos hará plantearnos 2004http://www.javaranch.com/journal/200409/DrivingOn CruiseControl_Part1.htm en ocasiones si merece la pena en esta situación [4] CVS. https://www.cvshome.org/ seguir manteniendo nuestro entorno de integración continua. [5] Subversion. http://subversion.tigris.org/ [6] Ant. http://ant.apache.org/ 7 Conclusiones: El poder de la [7] Maven http://maven.apache.org/ Automatización. [8] DBUnit . http://dbunit.sourceforge.net/ [9] Easy Mock Objects http://www.easymock.org/ l Es realmente sorprendente que equipos que

desarrollan programas para automatizar el trabajo en otros ámbitos, en muchas ocasiones no utilicen esta capacidad para automatizar su propio trabajo en lo posible. Detrás de los equipos más eficientes de desarrollo encontraremos generalmente un alto grado de automatización de su trabajo.

La integración continua es una práctica cuya implementación implica automatizar una de las tareas más pesadas y complejas de predecir: el proceso de integración del desarrollo en un entorno similar al final. Para implantar esta práctica el movimiento de Software libre nos proporciona herramientas muy potentes (CruiseControl, Ant, CVS, Junit, etc) que facilitarán este camino.

La Integración continua nos permitirá detectar de manera temprana posibles problemas de integración que puede tener soluciones muy complejas a posteriori. Alcanzaremos un grado de confianza alto sobre nuestro desarrollo al validarlo continuamente, con el conjunto de pruebas, en un entorno similar al final.

La integración continua minimizará el tiempo de puesta en producción acortando el ciclo desde que nuestro cliente nos pide un desarrollo nuevo o un cambio hasta que puede tenerlo en producción. Esto nos hará ser mucho mas ágiles con nuestro cliente, mostrándole en cada momento como evoluciona el desarrollo para que, junto con él, podamos llegar a la solución que mas valor le aporte.

Referencias

[1] Kent Beck, Extreme Programming Explained: Embrace Change, Addison-Wesley, 1999. [2] Martin Fowler y Matthew Foemmel. Título del Articulo: Continuous integration, ThoughtWorkshttp://www.martinfowler.com/articles/conti nuous Integration.html [3] Lasse Koskela. . Driving on CruiseControl., JavaRach Journal, September

114