martes, 8 de septiembre de 2009

Banco de experiencias (IV): librerías imprescindibles en Java

La máxima de Albert Einstein
"Everything should be made as simple as possible, but no simpler"
o la de Leonardo Da Vinci
"La simplicidad es la máxima sofisticación"
junto con el Principio KISS (que no es otra cosa que una aplicación del concepto de La Navaja de Occam a la informática) y el Principio DRY, forman parte de los principios básicos que todo desarrollador debería tener presente siempre, ya que, parece ser que el "sentido común" es menos común de lo que debería... o en todo caso, un concepto demasiado genérico.Una de las consecuencias directas de estos principios es la utilización de componentes probados reutilizables en nuestros proyectos, que nos facilitan el trabajo de manera incalculable, no sólo de desarrollo, sino también y sobre todo, de depuración y estabilización. Dentro de los miles de juegos de componentes en forma de API's, librerías y frameworks hay una reducida selección de joyas que he ido recopilando con el paso del tiempo y uso en casi todos los proyectos. Incluso en tecnologías de desarrollo, donde la transitoriedad y fugacidad de las mismas es tan enorme, algunos imprescindibles han ido perpetuándose y creciendo o evolucionando en el tiempo, convirtiéndose en estándares de facto y haciéndose completamente indispensables. Esta es mi lista de imprescindibles:

logback: Está en el primer puesto por algo. Absolutamente indispensable y de incorporación obligada en cualquier proyecto. Es la evolución de log4j, asi que supongo que no hay nada más que añadir.

JUnit: Otra indispensable. Cualquiera que piense que esto de las pruebas unitarias es un rollo para "cuando tenga tiempo" está muy equivocado. Al igual que usar logback es tan fácil como sustituir los cutres System.out.println(), usar JUnit es tan fácil como sustuir los cutres "main()" en las clases para probar métodos (...lo que vienen siendo pruebas unitarias, vamos...). Para probar métodos muy usados en un proyecto o muy específicos no hay nada mejor... tampoco se trata de crear unitarias para todas las clases!.

Apache Commons: Hay algunos que cuando entran en el enlace por primera vez ignoran la mayor parte del contenido, aturdidos por su enorme extensión o simplemente por desconocimiento. Sin embargo sugiero dedicar unos segundos simplemente a ojear las librerías existentes. Es impresionante. Tras unos instantes uno comprueba la cantidad de veces que habremos "reinventado la rueda" en algunos proyectos antes de conocer estas librerías. Aunque todas son susceptibles de ser útiles, voy a destacar las que considero imprescindibles y cuyo uso me ha reportado enormes satisfacciones:
  • IO: Un vistazo rápido a la guia de usuario te dará una idea de su potencial. Especialmente para aquellos casos de aplicaciones que tratan con nombres de fichero u operar con ficheros y directorios de forma compatible para distintos sistemas operativos.
  • Lang: Hay un excelente artículo de cómoda y atractiva lectura que te dejará claro por qué es absolutamente indispensable.
  • Configuration: Igualmente, hay otro buen artículo en el que encontrarás los ejemplos necesarios. Especialmente interesante es usarlo con el wrapper EAC4J para usar la configuración vía JNDI.
  • VFS: Cuando tengas que hacer un acceso a ficheros cuya ubicación es indeterminada, usa VFS. Es una capa de abstracción que te permite acceder a múltiples sistemas de ficheros (SMB, FTP, SFTP, HTTP, etc...). Por ejemplo, es ideal si tienes que acceder a ficheros que hoy son locales pero igual mañana están en un recurso compartido de un servidor Windows con autenticación, o una cabina de discos NAS...
HttpClient: Si necesitas hacer algo más allá de HTPP GET o POST, como usar HTTPS, proxies, cookies, etc... necesitarás HttpClient. Incluso en el caso más sencillo: es más cómodo, rápido y seguro que usar java.net.

    Específicas para JSF

    Para los desarrollos de JSF, tengo también mis imprescindibles específicos. Son los siguientes:

    facelets: Algunos kits o implementaciones ya lo incluyen, como ICEfaces. Si no lo usas, estás complicándote la vida: facelets simplifica.

    on-load: La solución para ejecutar código cuando se carga una determinada página.

    EasySI: ¿Harto de realizar conversiones manuales para cargar colecciones de SelectItem para publicar combos? Usa EasySI o <t:selectItems> de Apache MyFaces Tomahawk.

    Son todas las que están... pero posiblemente no estén todas las que son... ¿Hay alguna que uses frecuentemente que no esté en la lista?

    jueves, 27 de agosto de 2009

    Alternativas gratuitas de código abierto a MS Visio para Linux

    Este es uno de los temas más recurrentes de los usuarios de Linux: encontrar una una aplicación clon de MS Visio para Linux.

    Hay varias aplicaciones muy parecidas y con funcionalidades equivalentes, pero los resultados que se obtienen son muy diferentes a Visio. ¿Por qué? Pues fundamentalmente por la galería de objetos, formas y cliparts, que en Visio están muy bien realizados y cuenta con un catálogo de formas realmente enorme, no sólo por los que vienen "de serie", sino también por la amplia oferta de descarga adicional.

    Una vez puestas las expectativas en su sitio, está claro que podemos hacer diagramas en Linux. Especialmente para una gran mayoría de usuarios cuyas exigencias tampoco son precísamente muy sofisticadas. Estas son las alternativas:

    OpenOffice Draw

    Draw es un editor de gŕaficos vectoriales que se parece más a CorelDraw que a MS Visio, pero se puede instalar la Open Clip Art Library (Biblioteca Abierta de Clip Art), que permite agregar una enorme galería de banderas, logotipos, iconos y estandartes y pancartas para presentaciones generales y proyectos de dibujo.



    También puedes descargar ClipArts adicionales desde http://extensions.services.openoffice.org/project/oxygenoffice-gallery.

    Esta aplicación cumple perfectamente si el objetivo es crear diagramas varios para presentaciones o documentos. Si no tienes nada más a mano, es una solución rápida, gratuita y legal. Es la que uso más frecuentemente.

    OpenOffice está también disponible para OSX, FreeBSD y Windows.

    Kivio

    Kivio es la aplicación para diagramas de la suite KOffice. La verdad es que esta suite promete bastante, especialmente por la enorme cantidad de aplicaciones que incluye:
    • productividad (típico de cualquier paquete Office): procesador de textos, hoja de cálculo, presentaciones y base de datos (compatible MS Access, por cierto)
    • creatividad: diagramas de flujo, dibujo vectorial y imágenes de mapa de bits
    • gestión de proyectos (tipo MS Project)
    • y otras, como un generador de informes, así como herramientas para gráficos empresariales y editor de fórmulas.
    Me he instalado varias aplicaciones (Kivio, Kexi y KPlato) con el clásico "sudo aptitude install xxxx" y me han dado muy buenas sensaciones: aplicaciones de aspecto limpio y sencillo y muy ligeras y fluidas.



    En general el desarrollo de la suite, aunque está ya en su versión 2, sigue en su fase temprana y faltan aún temas por acabar pero, como decía, auguro un interesante futuro para esta suite.

    Kivio, en concreto, se parece enormemente a MS Visio y, probablemente sea su clon más exacto cuando esté definitivamente acabada. Los usuarios de Linux po drán empezar a probarla desde ya mismo. Los usuarios de Windows aún tendrán que esperar un poco más... pero estará disponible en breve.

    Supongo que Kivio acabará siendo al proyecto KDE lo que ha sido Dia a GNOME.

    Hoy por hoy es una opción a tener en cuenta, aunque la biblioteca de cliparts disponible es reducida.

    Dia

    Cuando comenzaba el artículo, comentaba que ésta solía ser una pregunta recurrente de los usuarios de Linux... y la respuesta recurrente en Internet siempre es ésta: Dia.

    Desarrollada en gtk+ (como parte del proyecto GNOME), es una aplicación diseñada como sustituto de Visio... pero supongo que inspirada en éste antes de que Microsoft adquiriese la compañía Visio, en el año 2000. La aplicación cumple su misión bastante bien, pero a mi particulamente se me antoja que tiene un diseño obsoleto (las aplicaciones multiventana no me gustan nada), no ha tenido últimamente mucha evolución (se ha actualizado recientemente, pero no lo hacía desde el 2007) y no me resulta cómoda.

    Debo reconocer, que siempre que me he propuesto usar Dia he acabado usando OpenOffice Draw. No obstante, recomiendo instalarlo y probarlo: puede ser que sea esto justo lo que estás buscando o que te guste a tí.


    En definitiva, por mi parte seguiré muy de cerca la evolución de Kivio, que me ha parecido realmente lo que yo busco. Mientras tanto, continuaré con Draw.

    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.
    Related Posts Plugin for WordPress, Blogger...
    cookieassistant.com