Propiamente hablando

Posted by Eduardo Millán on febrero 27, 2004
Filed under Java | 1 Comentarios

Bueno, pues de nuevo estoy aquí, con otro tip para Java, en este caso se trata de algo curioso que me ha pasado con la internacionalización, los archivos properties que se utilizan para traducir aplicaciones, y que una vez conozco, estoy seguro que traerá de cabeza a más de uno, al menos a mi me ha pasado hasta que descubrí la solución, por casualidad ;).

Para todos aquellos que programáis en entornos web para PDA's (¿Al?) seguro vamos, seguro que os ha ocurrido si habéis intentado internacionalizar la aplicación. ¿o no?

Bueno, el problema parte de que, como somos Latinos, pues nada, utilizamos acentos, eñes, y todo eso que a los americanos no les gusta XDD.

¿Cuál es el problema?, bueno pues que al final se cansan de nosotros y como ejemplo, si este texto estuviese internacionalizado, lo veríamos así:


Texto Latino Internacionalizado XDD

En definitiva, que no nos entienden XDD.

Bueno, hablando ya en serio, este es el problema que me ha ocurrido. Yo tan tranquilamente escribiendo los textos de internacionalización en mi archivo properties, y al visualizarlo en PDA's (en navegadores PC no me ha ocurrido, no sé por qué) me encuentro con este tipo de problemas.

NOTA: El problema me ha pasado concretamente al utilizar la internacionalización de Struts, pero según mis investigaciones es un problema común a los ResourceBundle creados con archivos properties según se desprende de la información existente en los javadoc de la API Java 1.4.

Afortunadamente :) el otro día buscando información acerca de los ResourceBundle creí encontrar la solución. El tema es que al guardar propiedades en archivos properties se utiliza el encoding ISO-8859-1. Para aquellos caracteres que no se pueden expresar en esta codificación, se utilizan códigos de escape Unicode con la partcularidad de que solamente se puede utilizar una "u" en la secuencia. Para la conversión de archivos entre diferentes codificaciones el JDK provee de una herramienta llamada native2ascii tanto para Windows como para Solaris (supongo que en Linux ya habrá herramientas de este tipo).

¡A jugaaaaaaaaarrrrrrr!

Si queréis hacer pruebas y tenéis definido el path al directorio bin del JDK, abrid una pantalla de consola y teclead:

      > native2ascii
    

Ahora podéis hacer pruebas. Meted palabras con acentos o eñes, y veréis cual es su representación correcta en archivos properties. Por ejemplo:

      están es est\u00a0n
    
      sartén es sart\u201an
    
      gañán es ga\u00a4\u00a0n
    

¿Qué mas palabras se os ocurren? ;)

 

 

Tomcat, Xerces y yo

Posted by Eduardo Millán on enero 15, 2004
Filed under Java | 5 Comentarios


Tratando de utilizar la, por el momento, mejor implementación de XForms, Chiba, me he topado con los problemas que tiene meter distintas aplicaciones en un mismo Tomcat, utilizar Xerces y aplicaciones web que dependen de Xerces.

¿Has tenido tú problemas con Tomcat, Xerces y TUs aplicaciones web?

XDD. Je, je.

No me sorprende en absoluto, hay bastante literatura escrita al respecto. Yo voy a intentar de resumir aquí los principales problemas que me he encontrado, supongo que si el servidor de aplicaciones que utilizas no es Tomcat (Weblogic, WebSphere, etc) tendrás similiares problemas que *tendrán* similares soluciones.

Pues eso, según he estado leyendo en la web de Tomcat este servidor de aplicaciones utiliza diferentes classloaders para la carga de clases, y se relacionan en forma de árbol. De forma que cuando un classloader necesita cargar una clase, primero delega este trabajo al padre, y si éste no consigue la carga de la clase entonces delega el trabajo al hijo (el classloader en cuestión).


      Bootstrap
          |
       System
          |
       Common
      /      \
 Catalina   Shared
             /   \
        Webapp1  Webapp2 ...

Tomcat añade una particularidad, y es que el classloader de cada webapp siempre va a tener preferencia sobre el resto. Así pues, desde el punto de vista de tu aplicación, la búsqueda de clases se realiza de la siguiente forma:

    * /WEB-INF/classes en tu webapp
    * /WEB-INF/lib/*.jar en tu webapp
    * Bootstrap classes en tu JVM 
                    - Runtime Java  
                    - $JAVA_HOME/jre/lib/ext
    * System class loader classes
                  - $CATALINA_HOME/bin/bootstrap.jar
                  - $JAVA_HOME/lib/tools.jar
    * $CATALINA_HOME/common/classes
    * $CATALINA_HOME/common/endorsed/*.jar
    * $CATALINA_HOME/common/lib/*.jar
    * $CATALINA_HOME/shared/classes
    * $CATALINA_HOME/shared/lib/*.jar

Además de estas reglas, hay una particularidad con respecto a las clases que forman parte de J2SE y que son cargadas por el classloader de cada webapp:

API SAX, API DOM, Xalan, Xerces y cualquier clase que empiece por javax.".

En este caso se delega la carga al classloader padre sin tener en cuenta la configuración establecida anteriormente. Además el classloader de cada webapp no va a cargar nunca las clases estándar java, aquellas que empiezan por java.*.

¿Queda claro el sistema de classloaders de Tomcat? ¿Sí? Bien, sigamos con las particularidades de la versión del JDK.

Xerces y JDK 1.4

Entre otros cambios, a Sun se le ocurrió la *feliz* idea de empaquetar la API JAXP junto con una versión de Xerces en su versión 1.4 del JDK. Esto supone un gran inconveniente en aquellas aplicaciones que quieran utilizar sus propias versiones de parseadores SAX y DOM, puesto que la versión incluida en el JDK tiene preferencia en la carga. Por ejemplo, cuando se ejecuta Tomcat con JDK 1.4 el proceso de delegación de classloaders va a elegir siempre la implementación presente dentro del JDK y no la existente en Tomcat.

Sun, para permitir que se pueda reemplazar versiones incluidas en el JDK, ideó un mecanismo llamado Endorsed Standards Override Mechanism que consiste en situar paquetes de clases Java (*.jar) en determinados directorios que reemplacen a los definidos por la JVM. Estos directorios suelen tener el nombre endorsed y para la JVM, por ejemplo se sitúa en $JAVA_HOME/jre/lib/endorsed. Tomcat tambien dispone de un directorio de paquetes endorsed: $CATALINA_HOME/common/endorsed, carga estos paquetes de forma que sustituyen a los definidos en el JDK.

Tercer problema: ¿Qué versión de Xerces necesitan nuestras aplicaciones?

Este suele ser el punto más crítico, ya que por la experiencia que he tenido NO todas las aplicaciones web soportan cualquier versión de Xerces y puede obligarnos a tener que instalar varias instancias de Tomcat para conseguir que todo funcione.

Conclusión

Para poder utilizar Xerces correctamente en nuestras aplicaciones web y Tomcat tendremos en cuenta las siguientes recomendaciones:

  • Averiguar la versión de Xerces que necesita cada una de nuestras webapps
  • Obtener las versiones de Xerces y Xalan (u otra API JAXP de transformación compatible) más recientes que cumplan los requisitos de las webapps
  • Instalar las versiones más recientes en $CATALINA_HOME/common/endorsed dentro del directorio de Tomcat
  • Quitar cualquier versión citada del directorio WEB-INF/lib de nuestra webapp
  • Rezar para que todo funcione (XDDDDD, NO, en serio... que sí que va... pffffffff)

Tengo que ver todavía el caso de Cocoon, que no sé por qué no me funciona con la última versión de Xerces...

 

Mezclando páginas web

Posted by Eduardo Millán on diciembre 17, 2003
Filed under Java | 1 Comentarios


Esta tarde he estado analizando un framework para visualizar o mezclar páginas web. Se trata de SiteMesh, es de la empresa OpenSymphony y fue anunciado por Martin en una noticia de javaHispano Según mi análisis, es un sistema de decoración de páginas web que trata de ofrecer un mecanismo para conseguir una integración en cuanto al aspecto (look and feel) de un sitio web.

Sinceramente, después de analizar el proyecto, me sorprende lo sencillo de su arquitectura. Se basa en un servlet filter que captura y procesa las peticiones HTTP aplicando un decorator según corresponda. Para decidir cuál es el decorator que aplica, utiliza valores de la página a procesar:

  • content-type
  • meta tags
  • css aplicado
  • user agent
  • lenguaje de la página (header accept-language)
  • parametros de la petición (request parameters)
  • otros...

Diagrama de flujo de SiteMesh

Arquitectura de Sitemesh (haz clic para ampliar)

Utiliza dos conjuntos de taglibs para manejar las páginas, sitemesh-decorator y sitemesh-page. La primera es para meter las partes de las páginas en la página marco (layout). La segunda es para instanciar a los decorators que se utilizan o para pasarles parámetros.

He tenido experiencia con Struts-Tiles y la verdad, si comparamos SiteMesh con Tiles, el primero se queda a años luz del segundo. La arquitectura de SiteMesh, aunque sencilla, es muy cerrada mientras que la de Tiles es más abierta y estructurada. De hecho, en Alba Software hemos extendido Tiles con muy buenos resultados. Por ejemplo, un gran defecto de SiteMesh es que utiliza page-includes en lugar de jsp-includes, lo cual te obliga a recompilar en cada cambio las JSP's que utilices.

Pongo este pequeño análisis aquí por si a alguien le sirve de ayuda, y para que no tenga que realizarlo él mismo. También acepto opiniones acerca del framework. Sigamos currando ;-)

 

Cocoon

Posted by Eduardo Millán on octubre 21, 2003
Filed under Java | 2 Comentarios

En estos días me estoy *peleando* con Cocoon. No, no es que no lo conociera todavía, me lo habían *presentado*, pero no en profundidad. Ya me sonaba del primer proyecto de documentación de Alba Software, aquella típica página de inicio tan similar a la que ahora conozco como página de inicio de los ejemplos de Cocoon 2.1. Que curioso.

Cocoon

El caso es que ahora lo necesitaba conocer más a fondo, me he paseado y utilizado el proyecto Forrest de Apache, y me ha parecido muy interesante. Se trata del proyecto de documentación de la ASF, y está basado en Cocoon. No sabía yo que Cocoon era tan potente, que incluso se podía utilizar sin atacarlo como servlet, es decir, mediante el *command line interface*.

Bueno, pues Cocoon en sí es todo un esquema de generación de documentos, más bien, generador de respuestas según coincidencias en la petición. A raíz de una URI que enviemos al servlet, se genera toda una serie de procesos, generación de entrada XML, transformaciones, serialización, etc; me ha dejado fascinado.

Solamente le veo un inconveniente, y es que cada uno de los componentes, está *desconectado del otro*, es decir, no van a compartir espacios de memoria, si no que se intercambian información en formato XML. Si esto es así, y lo que interesa es que todo el proceso de petición-respuesta esté *encadenado*, no alcanzo a entender como hacer para unir los componentes de un *pipeline*. Si, ya se, tenemos los actions que generan claves de sustitución (procesos que calculan variables y las hacen disponibles al siguiente componente), pero esto no me sirve porque... ¿que pasa si estamos hablando de arrays de datos?, la solución de Cocoon es una serie de tuplas clave-valor, y no veo como hacer cuando manejas otra serie de datos y los quieres pasar al siguente componente.

Realmente es un proyecto interesante, ya que todo el tema de generación de documentos de diferentes content-types está ya solucionado. En fins, seguiré investigando.

 

Aplicaciones web de escritorio

Posted by Eduardo Millán on septiembre 23, 2003
Filed under Java | 0 Comentarios



No es lo que habíais soñado? Si, si, estoy hablando de instalarte desde un CD o un .zip/.rar/.exe bajado de alguna web, la aplicación que tan bien te ha salido al desarrollarla.

Desde luego, es lo que hubiese deseado cuando trabajé en gestión durante tres años con el maldito VB y que entonces no se podía hacer porque la tecnología Java no estaba como está hoy... ¡en finsss!

Bueno, aquí va la historia, no os cuento el final XD.

Fuera del hilo de esto, alguien me podría decir qué es un "trackback" ¡asiasss!