lunes, 27 de julio de 2009

Banco de experiencias (III): errores comunes de despliegue en JEE

http://www.flickr.com/photos/nickwheeleroz/2475011402/in/photostream/

El problema

En JEE, además de la compilación y empaquetado, comunes en otras disciplinas java, existe un proceso imprescindible y no poco problemático: el despliegue.

Los errores de programación suelen ser detectados por el propio compilador y otras herramientas que ayudan a la detección de potenciales errores de ejecución. Sin embargo, hay ciertos errores de despliegue (es decir, errores que se producen en tiempo de despliegue y que te impiden incluso iniciar la aplicación para probarla) que no son fácilmente detectados por ninguna herramienta y que son un verdadero dolor de cabeza para los programadores por sus incomprensibles síntomas y difícil detección.

Existen también otros problemas, no dependientes directamente de nuestro código que se presentan durante el inicio o durante la ejecución de la aplicación. Este tipo de problemas son aún más difíciles de detectar, ya que los síntomas que encontramos no suelen tener ninguna relación con el código asociado al momento/lugar del código donde se producen o donde el servidor señala el error. Este tipo de problemas acostumbra a estar asociado también al despliegue o a algún bug del contenedor.

En este artículo ofrezco una checklist para cuando nos encontremos esas apuradas situaciones, en las que se nos han agotan las posibilidades y no sabemos dónde más mirar o qué más hacer.

Los síntomas

Los síntomas que nos encontramos en este tipo de errores son:
  • Un artefacto o componente JEE no se comporta como debe o simplemente no funciona en absoluto, sin embargo, el contenedor o servidor no reporta errores. Por ejemplo, un servlet correctamente declarado y desplegado no funciona y no hay errores en los logs.
  • El sistema reporta errores que aparentemente no tienen sentido. Por ejemplo, una clase o método que no se encuentra cuando comprobamos que está correctamente desplegado y accesible en el classpath.
  • Un segmento determinado de nuestro código no se ejecuta o termina de forma abrupta, y tampoco tenemos errores en los logs. Por ejemplo, un método de una clase implicada en un Resource Adaptor (conector JCA).

El diagnóstico

Se supone que ante los síntomas anteriores, ya hemos agotado todas las posibles opciones y orígenes típicos o supuestos que se nos ocurren, y especialmente, ya hemos descartado del todo (o casi del todo) que la causa sea nuestro propio código. Ante esto, ¿qué hacemos? ¿dónde está el problema? ¿dónde buscar?

Pues para esos casos y otros similares, aquí va una checklist que os será de utilidad:
  1. Revisar nuestro código otra vez, o lo que es mejor, que lo haga otra persona. Incluso en esos casos, lo normal es que el problema siga estando en nuestro código, así que, si lo has revisado dos veces: hazlo una tercera y que la cuarta lo haga otra persona.
  2. Comprobar que el path de despliegue no tiene caracteres multibyte. Algunas librerías que usan reflection, no están preparadas para cargar clases en paths con espacios o caracteres multibyte (eñes, acentos, etc...). Especialmente en sistemas operativos raros de ésos que algunos usan para desarrollar (como Haselfroch, por ejemplo). Ejemplo: toplink-essentials no funciona desplegado en un path con espacios.
  3. Cuidado con los despliegues "exploded". En algunas ocasiones nos interesa hacer despliegues desemplaquetados o descomprimidos. Si el directorio del módulo ha sido descomprimido fuera del sistema donde lo vamos a desplegar, puede haberse corrompido durante la copia o transferencia. Hay dos tipos de adulteración que pueden sufrir los ficheros:
    1. Corrupción binaria. En algunas ocasiones es posible que un fichero .jar (por ejemplo, de nuestras librerías) se corrompa al copiarlo y la aplicación no despliegue por esa causa.
    2. Alteración de nombres. Es posible, por ejemplo, que si se han copiado de un medio con un filesystem antiguo como FAT32 (case insensitive) acabemos con un directorio META-INF en minúsculas. Este tipo de errores es difícil de encontrar, pero nos crea problemas increíbles. Por ejemplo: la JVM no encontrará las dependencias declaradas en ficheros MANIFEST.MF en directorios meta-inf (así, en minúsculas).
  4. Revisa los descriptores. Este es uno de esos males provocados por el famoso "copiar y pegar" que tanto daño hace al desarrollo. Por ejemplo, para que funcione el maravilloso mecanismo Dependency Injection de JEE 5 en una aplicación web, es preciso que el descriptor del web.xml especifique expresamente la especificación Servlet 2.5. En definitiva, hay que revisar las cabeceras de nuestros ficheros descriptores y comprobar que ninguno es "heredado" de un proyecto anterior.
  5. Cuidado con los empaquetados automáticos de los IDE: revisa tus librerías. Cuando utilizamos librerías externas en varios proyectos, éstas suelen tener, además, sus propias dependencias que debemos incluir. Si nuestro empaquetado es automático vía algún IDE puede ocurrir que incluyamos varias veces una misma librería o distintas versiones de las mismas librerías sin darnos cuenta. Si además las librerías se cargan en ClassLoaders distintos, el caos está garantizado. Por ejemplo: este tipo de problemas suele provocar desconcertantes errores con "IllegalArgumentException" o "NoSuchMethodException" ya que el ClassLoader encuentra una versión más antigua de la librería que creemos que está usando.
  6. Traza, traza, traza. Y hazlo bien:  usa log4j o incluso mejor, usa su revisión: logback. Es importante saber en qué punto exactamente el sistema deja de hacer lo esperado.
  7. Revisa las secciones estáticas de tus clases. Las declaraciones de miembros estáticos o secciones estáticas (static {}) de una clase incluyen muchas veces constructores o llamadas a métodos que pueden, a su vez, generar un NPE (NullPointerException) indeseado. Cuando esto ocurre en una sección estática de una clase, la clase no puede ser inicializada y muchas veces obtenemos mensajes confusos tipo NoCassDefFoundError que nos despistan y no caemos en que todo se debe a un NPE nuestro. En las secciones estáticas, mantén el principio KISS. Por ejemplo, si declaras el típico private static final Pattern pRe = Pattern.compile("\\s*");, asegurate de que la expresión regular es válida o toda la clase entera no podrá usarse en tiempo de ejecución.
  8. Observa con detalles los logs del servidor y aumenta los niveles de trazado. Es frecuente que no hagamos caso al StackTrace que vuelcan los servidores en sus logs y simplemente nos fijemos en los más bajos de la pila (los últimos en listar). Mira con mayor detalle. Muchas veces te darán pistas sobre dónde buscar. Por ejemplo, me ha pasado escribiendo un Resource Adapter que un método ManagedConnection no se ejecutaba a partir de una determinada línea porque un bug del servidor "mataba" el thread cuando el contenedor llamaba a un método de limpieza. Al aumentar las trazas del contenedor de JCA me dí cuenta del problema (un NPE del contenedor en el dispose() de las conexiones).

Cuando tengas un problema de despliegue y empieces a quedarte sin opciones, vuelve a esta entrada y repasa esta lista de comprobaciones, es posible que te ayude... A mi me sirvió.

jueves, 16 de julio de 2009

Eclipse 3.5 Galileo + Glassfish: error instalando el plugin de Glassfish

Hace ya más de tres semanas que está disponible, o liberada, como dicen algunos (como si hubiera estado "presa" alguna vez..., en fin, esto de las traducciones libres...) la nueva versión de Eclipse, versión 3.5 y denominada "Eclipse Galileo", tras "Calisto", "Europa" y "Ganymede"... (va a pasar mucho tiempo hasta que se queden sin nombres).

Pues bien, mi estreno con esta nueva versión ha sido un poco decepcionante, ya que, tras desactivar el "spelling" (que sigue estando activado por defecto, usando 5,6Mb para nada), lo segundo que hago es instalar el plugin de Glassfish... y me encuentro con mi primera desilusión:

An error occurred while collecting items to be installed
No repository found containing: org.eclipse.update.feature,com.sun.enterprise.jst.server.sunappsrv.feature,1.0.29
No repository found containing: osgi.bundle,com.sun.enterprise.jst.server.sunappsrv,1.0.29
session context was:(profile=epp.package.jee, phase=org.eclipse.equinox.internal.provisional.p2.engine.phases.Collect, operand=, action=).


En efecto, es imposible instalar el plugin de eclipse según el modo tradicional, es decir, vía "download additional server adapter". Debe tratarse de algún bug circunstancial que solucionarán en breve (espero).

Mientras tanto, la solución es instalarlo vía Update URL a través de la URL: http://ajax.dev.java.net/eclipse. Ya sólo me queda instalar Subversive plugin para usar SVN y todo vuelve a ser como antes...

Que la disfrutéis.

[20/07/09] ACTUALIZACION: El comentario de un lector me informa de que es un bug conocido: https://bugs.eclipse.org/bugs/show_bug.cgi?id=280365. Thank you, finsterwalder.

martes, 14 de julio de 2009

Líala parda

Algunos recordaréis la expresión "la he liao parda" que una chica socorrista hizo famosa. Como afortunadamente todo quedó en un susto y no hubo consecuencias graves, pudimos reírnos de la anécdota, especialmente por la forma tan natural y sincera con la que se expresaba la chica al pedir disculpas. El vídeo en YouTube, (junto con otras copias) lo ha visto más de medio millón de personas, así que la expresión ha pasado a formar parte de las expresiones de moda colectivas, como consiguió Chiquito de la Calzada en su momento.

En fin, esta introducción viene a cuento del sitio www.lialaparda.com, desde el que puedes gastar una simpática broma y reírte un rato.

Os puedo garantizar que el sitio es de absoluta confianza... Probadlo y veréis ;-)



P.D.: sólo funciona con móviles de España.

miércoles, 17 de junio de 2009

XLS Office 2007 y anteriores con Java (SpreadsheetML incluído)

Apache POI es el framework de referencia y casi un estándar de facto para acceder a los formatos Microsoft usando un API Java Nativo. El subproyecto HSSF+XSSF de la versión 3.5 (aún en beta, pero totalmente funcional para el 90% de las operaciones) admite los nuevos formatos Open XML (como por ejemplo xlsx, introducidos en Office 2007). Y hasta aquí, aparentemente, todo solucionado. Si sólo pretendes importar/exportar datos, y no vas a usar funciones muy avanzadas, la Beta 5 de la versión 3.5 te va a funcionar perfectamente. No obstante, te puedes encontrar con alguna sorpresa desagradable en el lío de formatos de Office de MS. Concretamente la que se me ha dado a mí recientemente con un fichero Excel (xls) ha sido la siguiente:


Exception in thread "main" cestel.tk.uf.dao.file.DAOImportException: java.lang.IllegalArgumentException: Your InputStream was neither an OLE2 stream, nor an OOXML stream at cestel.tk.uf.dao.file.DAOHssf.loadAgenda(DAOHssf.java:79)
    ...

Obviamente se trataba de un fichero que se podía abrir en Excel normalmente, aunque me llamó la atención el hecho de que OpenOffice (al menos la 2.4) no era capaz de abrirlo como hoja de cálculo y en su lugar, presentaba el diálogo de importación. Abriendo el fichero con un editor de texto, me encuentro con que resulta que es un fichero XML con un contenido así:

1 <?xml version="1.0" encoding="UTF-8"?>
2 <?mso-application progid="Excel.Sheet"?>
3 <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
   xmlns:o="urn:schemas-microsoft-com:office:office" 
   xmlns:x="urn:schemas-microsoft-com:office:excel" 
   xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
   xmlns:html="http://www.w3.org/TR/REC-html40">
...
 
¿Y qué demonios es esto? Pues eso es, concretamente, SpreadsheetML, uno de los formatos de Microsoft Office XML, creados con anterioridad al Office 2007 y ya obsoletos, siendo sustituídos por los formatos Office Open XML (también llamados OOXML u Open XML)... y el problema está en que estos formatos no están soportados por Apache POI.

Afortunadamente, para estos casos, existe Xelem, una librería que te permite leer y escribir ficheros SpreadsheetML, con los que pude resolver el problema de la importación de datos.

viernes, 5 de junio de 2009

Sideralis: un Stellarium en tu móvil

Este año 2009 se celebra el Año Internacional de la Astronomía (declaración de la UNESCO ratificada por la resolución de la ONU en 2007). El AIA 2009 es la excusa perfecta para publicar una entrada a propósito de uno de los temas que más me han fascinado: la astronomía. Quizá este post debería haber sido el primero de todos, ya que el nombre de este blog se debe a mi atracción por la astronomía. Balteus es nombre que se le daba al cinturón que llevaban los legionarios romanos, también llamado cingulum, y que portaba la espada. También se ha llamado así al famoso trío de estrellas Alnitak, Alnilam y Mintaka, de la constelación Orión, una de las más conocidas de nuestro cielo. Este trío conforma el cinturón que porta la espada de Orion, típicamente conocido como "el cinturón de Orion" y también conocido como Al-Nijad (el cinturón), Al-Nasak (la línea), Balteus (el cinturón), "Los tres reyes", "Las tres marías", etc, etc... Siempre me han atraído esas tres estrellas alineadas.

Cuando miramos al cielo a simple vista nos puede parecer que estamos viendo millones de estrellas... pero nada más lejos de la realidad: raras veces llegamos a ver más de 300 (magnitud 4).. ¡y eso en el campo y en circunstancias perfectas!. Lo máximo que podríamos llegar a ver, en el mejor de los casos (a 4.000 metros de altura, sin luna, con cielo despejado y con una vista envidiable) serían 1.500, como mucho. Con este panorama, y teniendo en cuenta contaminación lumínica, cielos poco despejados y nuestra limitada vista, en la mayoría de los casos normalmente sólo alcanzamos a ver entre 30 (magnitud 2) y 100 (magnitud 3). Además, todas son del vecindario: de la Vía Láctea. De 200.000 millones de estrellas repartidas en un radio de 100.000 años luz de nuestra propia galaxia, apenas alcanzamos a ver unas decenas de estrellas... Aquí, en la ciudad de Madrid, en buenas condiciones, apenas se perciben, a simple vista, menos de una docena (sin contar Venus, que se ve perfectamente, pero no es una estrella). Ya que vemos tan pocas estrellas, ¿no os gustaría saber cuáles son? ¿cómo se llaman? En mi caso, sin referencias, y siendo un simple curioso/seguidor "de documentales" (ni siquiera me puedo considerar un aficionado a la astronomía), es prácticamente imposible saber qué estoy viendo... hasta ahora.

Los curiosos de la astronomía conocerán casi seguro Stellarium (el sitio web en español es éste). Probablemente uno de los mejores mapas de cielo (o mapa estelar, o planetario, como queráis llamarlo) para ordenador. Si no lo conoces, bájatelo y pruébalo. Aunque sea sólo por curiosidad. Es espectacular. Está disponible para varios sistemas operativos (e incluso para Windows). Probarlo es muy sencillo y, comprobar que lo que estás mirando por la ventana es lo que te aparece en la pantalla, es cuestion de unos pocos minutos. Es una forma muy divertida y agradable de introducirse en el fantástico mundo de la observación del cielo.

Cuando Galileo apuntó por primera vez al cielo con un telescopio, 400 años atrás, no creo que se imaginara que llegaríamos a tener un planisferio luminoso en un aparato minúsculo que, además (mira tú qué cosas), sirve también para llamar por teléfono y decirte la hora. ¡Por fin un móvil sirve para algo interesante!.

Sideralis es un equivalente a Stellarium, pero en tu móvil. Funciona perfectamente en mi N82 y, en principio, en prácticamente cualquier móvil más o menos reciente que soporte MIDP 2.0. La aplicación es muy completa: vistas horizonal y cénit, e información de más planetas, estrellas (más de 800) y objetos Messier de los que podamos ver incluso aunque tengamos unos prismáticos a mano.

La ventaja del programa es evidente. Si estás por la noche en un lugar despejado (o en cualquier sitio que puedas observar al cielo) sin haberlo podido planificar, es difícil que lleves un planisferio, una PDA o un PC encima... ¿pero el móvil? casi seguro que lo tienes a mano para arrancar esta maravilla y empezar a ponerle nombre a lo que ves.

Está disponible en español y además es gratuito. Sólo le falta (puestos a pedir) que tome la localización automáticamente del GPS integrado de los móviles que lo tengan. Desde aquí, le doy las gracias al autor por brindarnos gratuitamente esta joya


Ah!... y está hecha en Java, claro.

P.D.: por cierto, hay un post muy bueno sobre planetarios para Linux aquí.


ACTUALIZACIÓN [16/06/09]: La versión 1.2.7 (etiquetada internamente como 1.02(7)) ya incluye tres formas de posicionamiento: manual (introduciendo longitud y latitud), seleccionando tu ciudad, o vía GPS.

miércoles, 20 de mayo de 2009

Open Source BRE/BRMS JSR-94 compliant

El título está en inglés, pero es que "Motores de Reglas de Negocio o Sistemas de Gestión de Reglas de Negocio compatibles JSR-94 de código abierto" es un título muy largo y, cuando buscamos información, se suele buscar más usando los términos en inglés.

Recientemente he tenido sondear el estado del arte de los BRE/BRMS de código abierto y lo primero que encontré es que hay decenas (concretamente hay 30 en esta lista de noviembre de 2007). Obviamente, no tengo tiempo de evaluar tantos proyectos, así que establecí una serie de criterios de búsqueda que me redujesen la lista de resultados a una cantidad aceptable para evaluar o, al menos, leer y recopilar información para una posterior evaluación.

Los criterios de búsqueda que establecí son:
  • BRE mínimo (se excluyen "compiladores" de reglas)
  • Conformidad con la JSR-94
  • Proyecto activo (considero "activo" un proyecto con actividad reciente inferior a 2 años)
  • Ligero, con persistencia y repositorio autónomo (es decir, que aunque pueda usar una base de datos no la necesite necesariamente)
  • Documentación suficiente o aceptable.
El resultado de la recopilación es:
  • Drools / JBoss Drools / Jboss Rules
  • OpenRules
  • Hammurapi Rules
  • SweetRules
  • JRuleEngine

Aunque muchos BRE evolucionan a un BRMS, lo cierto es que BRMS no hay muchos, con lo que la recopilación se queda en un número más pequeño del que me imaginaba. Además, el criterio de conformidad a la JSR-94 ha sido suficientemente restrictivo, ya que excluye todos los que no son Java y además, son muy pocos los que cumplimentan la especificación.


Drools (JBoss Drools / JBoss Rules) 
Probablemente el más conocido, y también el más gigantesco de los proyectos. Se puede considerar un BRMS en toda regla ya que tiene herramientas típicas de los BRMS propietarios (repositorio, editor de reglas WUI,etc)
Las reglas pueden escribirse en DRL (el típico), Java, Groovy... incluso puede extenderse con DSL's vía XML.
Para mi, quizá uno de los puntos fuertes de Drools sea la integración con el resto de servicios de middleware de jBoss, especialmente con jBPM. La versión 5, se espande en un elenco de servicios realmente impresionante, que promete bastante.
Curiosamente, tiene  un porting a .NET.


OpenRules
Este es el proyecto que más me ha llamado la atención por novedoso, curioso y de aplicación práctica inmediata. Desdel el punto de vista de la existencia (y variedad) de repositorios y herramientas, estamos ante un BRMS (Drools y éste son los únicos de la lista). La característica más destacada de OpenRules es la versatiliidad y adaptabilidad, ya que:
El sitio web está muy bien organizado, tiene muchos ejemplos, y la documentación es bastante buena. Me ha impresionado, realmente.

Como curiosidad, está votado como el más popular en javarules.org.


Hammurapi Rules
Es más un BRE que un BRMS, aunque tiene una arquitectura multithread muy bien diseñada. Una ventaja interesante es que el lenguaje elegido para las reglas es el propio Java, con lo que la curva de aprendizaje es muy pequeña. Además, siendo realistas, pocas situaciones hay en las que existe el famoso "analista de negocio" que es capaz (y además quiere hacerlo) de definir las reglas de negocio en un lenguaje "informático" (y eso suponiendo que los objetos de negocio no cambien mucho).

Me parece una buena opción para casos en lo que nos biene especialmente bien escribir las reglas en Java y queremos "empotrar" un BRE en nuestra aplicación fácilmente. Por ejemplo, para migrar a una aplicación con muchas reglas hard-coded a reglas modificables en caliente sin demasiado impacto.

SweetRules
Aunque no es conforme a la JSR-94, me llamó la atención que es el único que implementa RuleML, el que se propone como lenguaje de reglas estándar. No obstante, la web es caótica, y la documentación deja mucho que desear. La implementación de RuleML es la única curiosidad.

JRuleEngine
Probablemente es el BRE más ligero de los 5. Las reglas se escriben en XML y no he visto que implemente Rete. No obstante, parece cumplir con los mínimos.


Al final, junto con Drools (¿cómo no?) el proyecto que más me ha gustado es OpenRules. Hammurapi Rules también es bastante interesante. ¿Crees que he omitido alguno que debería estar? ¿hay alguno que te parezca especialmente interesante? Agradeceré comentarios al respecto.
Related Posts Plugin for WordPress, Blogger...
cookieassistant.com