David Sanmartín Blog

Tag: Glassfish

Configuración de log4j en Glassfish para desarrollo

by David Sanmartín on Nov.20, 2009, under Eclipse, Glassfish, Tecnología

Bueno, después de un tiempo sin escribir nada nuevo y no por no encontrarme con problemas curiosos, sino por falta de tiempo, aquí estoy con un nuevo artículo. Esta vez el problema fue configurar el log4j para un nuevo proyecto. Realmente es un problema con el que ya me encontré hace tiempo y que solucioné en su momento pero que había quedado olvidado en mi subconsciente.

Configurar log4j para una aplicación web es una tarea bastante sencilla y que no presenta demasiados contratiempos si no hay errores de sintaxis. Aquí he de hacer un apunte para decir que suelo configurar el log4j con un fichero log4j.properties y no con un log4j.xml. No hay una poderosa razón detrás, sólo viejos hábitos.

Pero sigamos con la explicación. Si la aplicación web que hemos realizado la desplegamos sobre Glassfish, bien dejándola en la carpeta autodeploy o bien desde la interfaz web de configuración de Glassfish, el log4j nos funcionará sin problemas y podremos ver en el fichero server.log los mensajes que hayamos configurado para mostrar desde log4j (si hemos puesto que el appender sea ConsoleAppender). Pero si estamos desarrollando la aplicación web desde Eclipse y tenemos configurado el servidor Glassfish dentro del Eclipse es posible que nos encontremos con el mismo problema con el que yo me encontré: el log4j no escribe en el server.log.

Después de muchos quebraderos de cabeza comprobando que la configuración del log4j es correcta e incluso eliminando el 95% de la configuración para dejar sólamente un logger y un appender, no había forma de ver las entradas que supuestamente estaba escribiendo en el log. Aunque esto no es del todo cierto, ya que sí que podía ver los mensajes que tenían un level igual o superior a WARN. Este dato es curioso ya que en mi log4j.properties había configurado el logger para TRACE. Todo hacía indicar que se estaba cargando una configuración que no era la que yo indicaba en el fichero con el que estaba tratando. Entonces tocó revisar que Glassfish no tenía más aplicaciones desplegadas, que no tenía más proyectos abiertos en Eclipse (hay que ver las cosas que hacemos cuando algo nos falla y nos frustramos) y que no había ninguna otra posible configuración cargándose ni desde un fichero .properties, .xml o desde Java.

Fue entonces cuando me puse a googlear y di con un mail de la lista de correo de Struts2 en el que uno de los participantes daba un enlace a una página de la wiki de Glassfish, donde se explica cómo resolver este problema. Como la página está en inglés y no encontré ninguna otra web donde se comentara este problema pues voy a poner aquí los pasos para corregir este problema en castellano.

  1. Crear una carpeta llamada logging dentro de la carpeta lib del dominio para el que queramos configurar el domain.
  2. Dejar el .jar del log4j dentro la carpeta recién creada logging.
  3. Dejar también el fichero de configuración de log4j.
  4. Arrancar el servidor y acceder a la interfaz web de configuración de Glassfish. Lo normal es que accedamos a ella con http://localhost:4848/.
  5. Vamos a la sección Application Server, luego hacemos click en la pestaña JVM Settings (o Configuración JVM si lo tenemos en castellano) y después en Path Settings (o Configuración de ruta).
  6. En el textarea correspondiente a System Classpath (Ruta de clase del sistema) debemos escribir la ruta completa hasta el fichero .jar incluyendo el nombre del propio fichero .jar y también la ruta completa de la carpeta logging que hemos creado.
  7. Una vez hecho esto le damos a Guardar y reiniciamos el domain.

En mi caso (esta vez) sólo tuve que modificar el fichero log4j.properties que se encontraba en la carpeta logging para añadir la configuración del nuevo proyecto. Esto es lo que hay que hacer cada vez que queramos desarrollar una nueva aplicación.

La información ha sido obtenida de aquí.

1 Comment :, , , more...

Struts2 FileUploadInterceptor & Content-Type

by David Sanmartín on Aug.13, 2009, under Struts2, Tecnología, Uncategorized

Tras desarrollar una aplicación para un cliente en Struts2 un día recibimos una incidencia sobre un comportamiento extraño que tenía lugar al subir un fichero. Resulta que el formulario se enviaba sin problemas y se devolvía la correspondiente página indicando que se había modificado correctamente la información. Pero el fichero enviado no se había subido al servidor.

Después de que mi compañero David Canós reprodujera la incidencia en su ordenador me puse a averiguar si había algo en el formulario o en el Action que lo recibe que pudiera ocasionar el error. Activé el log y al probarlo en mi ordenador descubrí que a mi me funcionaba de la forma esperada. No obstante el log predijo que el error se debía a que el servidor no detectaba un Content-Type en el fichero enviado. Cogí el mismo fichero que había probado mi compañero (después de que me lo enviara por mail y también me lo pasara con un pendrive) y me seguía funcionando bien. Entonces pensé que se habría seteado el mime durante la copia de un SO a otro (aunque gastemos el mismo SO) y se lo reenvié para que probara una vez más. Volvió a fallarle. Probó también con otros ficheros y con otros le daba el mismo problema.

Llegados a este punto me puse a pensar y recordé que mi compañero usaba Chrome normalmente y en la empresa donde ocurrió el problema usan Safari (pues principalmente trabajan con Mac) así que no podía ser por un problema del navegador. Pero yo lo había probado con Firefox y con IE7 así que le dije a mi compañero que probara una vez más pero desde Firefox. Cuál fue mi sorpresa cuando el fichero (el mismo de todas las veces) se envió correctamente. Sabiendo el origen y el motivo sólo quedaba arreglar el error. Y ahora es cuando viene lo más divertido: modifiqué la configuración del servidor para que contemplara las extensiones extrañas (app.log.001 por ejemplo) y les asignara por defecto ‘text/plain’ como Mime-Type, pero el problema seguía ocurriendo. Por tanto la solución residía en Struts2 y más concretamente en el FileUploadInterceptor.

Me descargué el código fuente del core de Struts2 para poder acceder al código fuente del FileUploadInterceptor. Después de comprender el proceso del interceptor y de poner un par de System.out para comprobar el momento en el que estaba fallando el código hice la siguiente modificación:

Código antiguo:

...
// Bind allowed Files
Enumeration fileParameterNames = multiWrapper.getFileParameterNames();

while (fileParameterNames != null && fileParameterNames.hasMoreElements()) {
    // get the value of this input tag
    String inputName = (String) fileParameterNames.nextElement();

    // get the content type
    String[] contentType = multiWrapper.getContentTypes(inputName);

    if (isNonEmpty(contentType)) {
        // get the name of the file from the input tag
        String[] fileName = multiWrapper.getFileNames(inputName);

        if (isNonEmpty(fileName)) {
            // Get a File object for the uploaded File
...

Código generado:

...
// bind allowed Files
Enumeration fileParameterNames = multiWrapper.getFileParameterNames();

while (fileParameterNames != null && fileParameterNames.hasMoreElements()) {
    // get the value of this input tag
    String inputName = (String) fileParameterNames.nextElement();

    // get the content type
    String[] contentType = multiWrapper.getContentTypes(inputName);

    if((contentType.length < 1) || (contentType[0] == null)){
        contentType = new String[]{"text/plain"};
    }

    if (isNonEmpty(contentType)) {
        // get the name of the file from the input tag
        String[] fileName = multiWrapper.getFileNames(inputName);

        if (isNonEmpty(fileName)) {
            // get a File object for the uploaded File
...

De esta forma consigo que si el fichero no trae ningún Content-Type le asigno por defecto el ‘text/plain’ para que no me falle. Por supuesto también me toco modificar la configuración del fichero struts.xml para poder usar mi FileUploadInterceptor modificado en vez del que trae Struts2 en la pila de interceptores ParamsPrepareParamsStack.

La moraleja es que parece que ni Safari ni Chrome le setean el Content-Type de la petición HTTP o uno por defecto al fichero que se envía en un formulario aunque este no tenga Content-Type.

5 Comments :, , more...

Contenido estático en Glassfish v2: alternatedocroot

by David Sanmartín on Jun.17, 2009, under Glassfish

Después de mucho tiempo tratando con la configuración de Glassfish y tras varios quebraderos de cabeza me he decidido a escribir este artículo para tratar de aclarar un poco el tema de servir contenido estático con Glassfish.

La propiedad alternatedocroot de Glassfish se asemeja en parte a la directiva Alias del servidor web Apache. Esta propiedad nos va a permitir acceder a carpetas que están fuera del contenedor del servidor. Una de las ventajas que nos puede proporcionar este hecho es que podemos tener las imágenes del proyecto fuera del mismo, disminuyendo así, por poner un ejemplo, el peso del fichero .war a desplegar.

Lo primero que hay que saber es que no hay que tocar la configuración de Glassfish para conseguir nuestro objetivo de servir contenido estático, sino que debemos modificar el fichero sun-web.xml de nuestro proyecto java. Para ello tenemos que añadir la siguiente propiedad dentro del elemento sun-web-app:

<sun-web-app ...>
....
<property name="alternatedocroot_1" value="from=/{ruta virtual}/*
        dir={ruta física}" />
....
</sun-web-app ...>

Explicamos a continuación cada uno de los elementos. En el name tenemos que indicar la propiedad de la configuración de Glassfish que queremos definir para este proyecto. Si quisiéramos definir más de un elemento de este tipo simplemente habría que iterar el número del nombre del alternatedocroot.
El campo value se compone de dos partes:

1. Elemento from: indica a partir de qué dirección URL se ha de servir el contenido estático.
2. Elemento dir: indica la ruta física donde tengamos almacenado el contenido estático.

Con un ejemplo se ve claro:

<property name="alternatedocroot_1" value="from=/img/* dir=/srv/web/img/"/>

Esta propiedad está indicando al servidor Glassfish que las consultas realizadas sobre la dirección http://localhost/img/ serán resueltas buscando la información en la carpeta /srv/web/img/. En caso de tener el servidor sobre Windows la propiedad se escribiría de la siguiente forma:

<property name="alternatedocroot_1" value="from=/img/* dir=c:\server\img\"/>

Es importante tener en cuenta que el nombre de la última carpeta de la ruta física ha de coincidir con el nombre de la ruta virtual. En el caso en que pusiéramos dos carpetas en el elemento from, dichas carpetas deberían ser las últimas de la ruta física.

Para terminar voy a poner un enlace del que he sacado gran parte de esta información, aparte de los foros de Java de Sun y el “ensayo-error”. El enlace es del blog de Jan Luehe, uno de los desarrolladores de Glassfish:

http://blogs.sun.com/jluehe/

Leave a Comment :, more...

¿Buscas algo?

Escribe en el campo a continuación lo que estás buscando:

¿Todavía no lo has encontrado? Deja un comentario en un post o contáctame para que yo me ocupe.

Posts

Todos los posts, ordenados cronológicamente...