Mar 28

Windows pirated edition

Windows pirated editionEl otro día me tocó hacer una demo delante del cliente. Mi jefa, la jefa de proyecto y yo nos desplazamos a las instalaciones del cliente. Allí, en una sala de reuniones nos esperan dos Capitanes de Fragata (equivalente a Teniente Coronel) y dos capitanes de Corbeta (equivalentes a Comandante).

Ante ese público saco mi portátil, lo conecto al proyector que ya estaba encendido. Enciendo el portátil, aparece en el pantallón el inicio de sesión de Windows. Entro en sesión y lo primero que aparece en grande, delante de todos, mi fondo de escritorio. Sí, ese mismo, el de la foto: Windows pirated edition, service crack 2, right to copy.

En fin, eso me pasa por no ser corporativo y tener mi propio fondo de escritorio en vez de el que nos impone la empresa. Afortunadamente todo el mundo se lo tomó a cachondeo.

Mar 25

Subir ficheros al servidor con JSP

 Dentro de la aplicación web que estamos haciendo, tenemos que permitir al usuario subir ficheros al servidor. Sé cómo se suben ficheros al servidor en PHP, pero nunca lo había hecho con JSP. Pensé que sería similar, pero me he encontrado con algunas sorpresas.

La primera sorpresa ha sido buscando en google. Unas búsquedas rápidas no me ha dado ningún resultado en el que se suba el fichero sin necesidad de librerías adicionales. Pensé que sería igual que con Apache/PHP, el servidor sube el fichero a una carpeta temporal y una variable le indica a nuestra aplicación PHP dónde está. En Tomcat/JSP parece ser que no es así. Insisto, quizás sí, pero no he buscado en profundidad.

Todos los resultados de google que he visto hacen referencia a que hay que usar alguna librería externa, como apache-commons-fileupload. Así que me puse a ello, usando esa librería.

La segunda pega es que al ser el form de html enctype="multipart/form-data", necesario para poder subir un fichero, en la parte del servidor JSP dejan de funcionar los request.getParameter(), siempre devuelve null. Resulta que si el request es multipart/form-data, hay que tratarlo de otra manera. Este asunto me ha llamado la atención y le ha hecho perder un puntito a JSP frente a PHP (o a Tomcat frente a Apache, no sé quién es el culpable), donde parece que  no hay esos problemas.

¿Y cómo se leen entonces los parámetros de la petición?. Pues nuevamente una búsqueda rápida en google parece indicar que la única solución es usar librerías externas y en concreto, la misma apache-commons-fileupload. Con esa librería se "parsea" la petición y obtenemos una lista de FileItem. Cada uno de ellos puede ser un fichero al que se ha hecho upload…. ¡¡ o uno de los parámetros !!. Llamando a los método getFieldName() y getString() (comprobando previamente si es parámetro o fichero) de esos FileItem obtenemos los valores.

En fin, algo que me ha parecido rebuscado y demasiado complejo frente a cómo se hace en PHP/Apache. Un pequeño tutorial de esto en la chuwiki: File Upload con JSP.

Mar 15

Cosas importantes

Hoy tengo muchas cosas importantes que hacer en el curro.

Hay un dicho que dice “cuando todo es importante, es que nada lo es”

Creo que me voy a dedicar a “googlear” un rato, o a escribir este post.

Mar 10

Malditas variables estáticas

En una aplicación más o menos grande y seria de java es normal leer algún fichero con propiedades de configuración para nuestro programa. Esas propiedades suelen ser múltiples y variadas, para módulos de todos los niveles que no tienen nada que ver unos con otros.

Una opción es leer ese fichero de propiedades desde un sitio cercano al main() de nuestra aplicación e ir pasando estas propiedades a los distintos módulos. Si hay módulos en varios niveles, estos deberán ir pasándose las propiedades de unos a otros, ya que el main() posiblemente no pueda acceder directamente a los módulos de bajo nivel.

Para evitar este trasiego de propiedades por todo el código, tiendo a hacer un código java de este estilo

public class FicheroPropiedades {

   private static String pathFicheroPropiedades = "path/fichero.properties";

   private static Properties propiedades = null;

   static {
      propiedades = cargaFichero();
   }

   public static String getProperty (String key) {
      return properties.getProperty(key);
   }
}

Es decir, una clase con todo estático a la que pedir los valores de las propiedades y un inicializador estático de forma que el fichero de propiedades se cargará en cuanto alguien "mencione" esta clase.

Pues bien, esto son todo problemas para los test de JUnit.

Por un lado, posiblemente tengamos o queramos un fichero de propiedades específico para nuestros test. O queramos cambiar alguna propiedad en algún test. Al leer nuestro código bajo test las propiedades de esta clase, es necesario hacerle cosas a esta clase para poder modificarla a gusto. Por ejemplo, poner public el path del fichero para poder cargar un fichero distinto en los test, o poner un cargaFichero(path), o añadir un setProperty() para modificar alguna propiedad concreta, o cualquier otra modificación que se os ocurra. Pero eso no es bonito. No es bonito tener que modificar una clase de nuestro código real para poder manejarla desde los test.

Por otro lado, si tenemos alguna herramienta que ejecuta automáticamente todos los test, es posible que esta clase sólo se inicialice en la ejecución del primer test, manteniendo sus valores para el resto de test. O que al pasar algún test que modifica propiedades, las deje modificadas para el siguiente. En fin, que podemos tener problemas en función de qué test se ejecuten primero, o si añadimos un test nuevo que modifique estas propiedades, puede alterar el resultado de los que van detrás.

Este es otro motivo, además de la mantenibilidad del código, para no usar/acceder a atributos estáticos desde todo el código  si no es realmente necesario. Los test de JUnit pueden hacerse dependientes del orden en que se ejecutan, ya que unos pueden cambiar o no los valores de estas variables estáticas según sus necesidades, incordiando a los que vienen detrás.

Aunque sea un poco rollo a la hora de codificar, suele ser mejor pasar las cosas a cada módulo a traves de métodos set() o en el constructor, aunque sea todo de golpe con un setProperties(Properties), que andar inicializando automáticamente variables estáticas y acceder a ellas desde todos sitios.

Mar 08

Sigo con javascript, jquery, datatables…

Nunca había trabajado con javascript y en mi desconocimiento era un lenguaje que me negaba a usar. Por un lado, en muchos sitios hablan de navegadores que no ejecutan javascript, por otro lado hurgar en la página con javascript parece que no debía ser muy amigable para los buscadores. El caso es que le tenía un poco de manía al lenguaje, sin conocerlo siquiera.

Pero al final he tenido que meterme con ello y es un lenguaje que me está gustando y llamando la atención. Veo que tiene muchas más posibilidades de las que pensaba. Y lo que más me ha gustado son las librerías que hay hay hechas que permiten hacer grandes cosas con pocas líneas de código.

He empezado un poquito con jQuery, nada más usar algunos widgets que me venían bien para la aplicación: diálogos y pestañas.

Y también, buscando como pintar un <table> con posibilidad de ordenar columnas me he encontrado con DataTables. basado en jQuery y con un montón de posibilidades fáciles de usar. Permite ordenar, filtrar buscando entre las celdas de la tabla, paginado, etc, etc.

La única pega que le veo es la misma que a CSS, cada navegador es de su padre y de su madre y el código javascript enseguida tiene que andar con cosas como "if internet explorer …"

De todas formas, empiezo a pensar que es un lenguaje que merece la pena y me pongo como tarea usarlo con más frecuencia en mis paginillas.

Mar 03

Sufriendo de nuevo a Internet Explorer

Hace ya algunos años me dio por aprender CSS. Recuerdo el pequeño infierno que fue aquello por culpa de Internet Explorer. Muchos navegadores cumplen el estándar de CSS y muestran las páginas web de acuerdo a ese estándar, pero entre esos muchos navegadores no se encuentra Internet Explorer. Este navegador interpreta CSS a su manera, por lo que la página que se ve bien con otros navegadores, no se ve bien con Internet Explorer. Al final debes probar tu página con varios navegadores, buscar la forma que que el CSS valga para todos ellos, o usar los famosos hacks para internet explorer.

Ahora que ando jugando con JavaScript, me encuentro con exactamente el mismo problema. Suelo usar Google Chrome, mi compañero de proyecto usa FireFox y en ambos exploradores vemos bien la aplicación. Pero … ¡¡ AY de mí !!, se me ocurrió abrir la aplicación con Internet Explorer y, efectivamente, como no podía ser de otra forma, no salía nada de nada.

El problema que daba Internet Explorer es que un document.getElementById("cosa") daba error "el objeto no acepta la propiedad o método". ¿Error de sintaxis? no, los otros navegadores lo hacían bien. Y googleando encuentro que Internet Explorer (al menos versiones 6 y 7) hacen una cosa rara con los id de los tag html, los name de los tag html y las variables globales de javascript. Básicamente, que todo id y name que encuentra lo convierte en variable global. Por lo que si tu código tiene un name, un id y/o una variable global con el mismo nombre, tienes un problema seguro.

Efectivamente, ese era el problema. Si yo quería obtener mi div con id="panel", en javascript había puesto

panel = document.getElementById("panel");

y ya estaba el lío montado. Afortunadamente, después de un par de horas de búsqueda en google, el arreglo se hizo en menos de dos segundos.