Java

PrimeFaces (JSF2). Cómo detectar el fin de carga de la página con JavaScript

Primefaces  es una librería que implementa JSF2, de modo que facilita la creación de aplicaciones Web en un entorno J2EE a través del uso de componentes prefabricados como menús, botones, tablas de datos, formularios, etcétera. Puedes encontrar demostraciones de su potencial y un catálogo de sus componentes en este enlace: http://www.primefaces.org/showcase/

Aunque se use Primefaces, el resultado que llega al navegador siempre es el mismo: un conjunto de etiquetas HTML junto con complejas implementaciones en JavaScript que se generan automáticamente a partir del código Java y de componentes en XHTML. Como todo sistema que abstrae al programador de los niveles inferiores, siempre es complicado realizar algunas operaciones específicas que se salen de lo establecido para la tecnología.

Tal es el caso de la detección de cuándo se ha terminado de cargar la página y el usuario tiene toda la información para operar. Habría que distinguir dos fases de forma genérica:

  • Carga de la estructura HTML de la página
  • Carga de las llamadas asíncronas (AJAX) para la obtención de datos.

En muchas ocasiones JSF2 (y por ende Primefaces) utilizan AJAX para obtener los datos del servidor, lo que implica que la página puede haber cargado su estructura y scripts, pero éstos continúan con su ejecución. El resultado es que el usuario no puede utilizar la página hasta un poco después de que el navegador le haya notificado que ha acabado: faltan tablas por completar, combos, datos dinámicos, etcétera.

Sería bueno por lo tanto contar con un mecanismo que nos permitiese realizar alguna acción cuando se ha terminado esa carga de datos. Se puede usar en algunas ocasiones cuando los que nos ofrece PrimeFaces no es suficiente: por ejemplo bloquear la pantalla con un fondo e icono de carga hasta que no esté plenamente operativa en la primera carga.

Como PrimeFaces utiliza jQuery para operar, simplemente aprovecharemos la posibilidad que nos brinda esta librería de Javascript: se enlazan un document.ready dentro de otro, de modo que el segundo se ejecutará cuando haya acabado el primero, que es el que contiene todas las operaciones de PrimeFaces

$(document).ready(function(){
    $(document).ready(function(){
        //Código Javascript que queramos ejecutar después de Primefaces
    });
});
Anuncios

Diseño dirigido por testing continuo (CTDD) en Eclipse con Infinitest

Si usas habitualmente del desarrollo guiado por test (Test Driven Development) seguro que te has hartado de ejecutar test y test hasta llegar a ver la señal de color verde que indica que los test han pasado.

Si no has probado nunca el TDD, te lo recomiendo. Básicamente (y de forma seguramente imprecisa, pero por motivos didácticos…) se resumiría en:

  1. Se crea un test que debería cumplir el código que voy a programar.
  2. Se ejecuta el test y se falla, obteniendo una señal de color rojo (como un semáforo).
  3. Se programa el código mínimo que hace que el test se cumpla.
    1. Se ejecuta el test y se puede obtener una señala roja de fallo, por lo que hay que modificar el código.
    2. Se ejecuta el test y se obtiene una señal verde que indica que el test ha pasado.
  4. Se genera otra vez otro test con más requisitos que debe cumplir.

La ejecución de los test se realiza en el IDE o a través de herramientas como Maven o un sistema de integración continua. Si lo hacemos en nuestro IDE, puede ser algo tedioso ya que tenemos que ejecutarlo manualmente cada vez que queramos probar si nuestro código hace cumplir el test que hemos creado.

  1. Programamos el código que se supone que pasa el test unitario.
  2. Localizamos la clase del test (unitario) que corresponde al fragmento de código que hemos programado (a veces se nos pierde entre un tumulto de pestañas).
  3. Ejecutamos el test.
  4. Vemos el resultado.
    1. Y si ha fallado, vuelta a empezar.

Aunque en los ID como Eclipse es fácil con las teclas cmd+alt+R+T (quizá no tanto jeje), podemos acabar algo cansados.

Para evitar esto podemos utilizar un plugin que nos permite realizar testing continuo (Continuous Test Driven Development – CTTD) esto es, que cada vez que modificamos un fichero de código, los test asociados a él se ejecutan en segundo plano de modo automático y sin intervención del desarrollador), obteniendo el resultado de los mismos en un lateral de la pantalla.

Aunque automatizar la ejecución continua de test puede ser algo muy básico, es de gran ayuda. Sintetizaría sus ventajas en los siguientes puntos:

  • Evita perder tiempo porque no tenemos que localizar el test que le incumbe al código modificado, o no tenemos que correr todos los test (porque no queremos localizar el test).
  • Quizá nos pueda evitar dar alguna vuelta de más al código al tener de forma más constante el resultado del test.
  • Y lo más importante: Ayuda a enfocarse todavía más en el paradigma TDD al proveer un feedback continuo de nuestras acciones.

Si buscamos herramientas CTTD para Eclipse, que es el IDE que suelo utilizar, aparecen unas cuantas. He probado una que parecía sencilla. Se llama Infinitest. Vamos a ver cómo se instala y se utiliza. Es muy fácil.

Infinitest

Screenshot from 2014-11-22 10:39:41

Infinitest está disponible para Eclipse e IntelliJ IDEA en forma de plugin que se integra perfectamente con el navegador. Su modo de funcionamiento se puede resumir en estos pasos:

  1. Primera ejecución: pasa todos los test que hay en el proyecto para conocer qué código está cubierto por cada test. De este modo, cuando salvemos un fichero, sabrá qué test tiene que ejecutar, evitando tener que correr todos otra vez.
  2. Siguientes ejecuciones: cuando salvemos un fichero de código, comprueba qué test se le aplican y los ejecuta en segundo plano, informando del resultado de dos modos (en Eclipse):
    1. Mediante un indicador en la zona inferior izquierda con el típico semáforo verde – rojo de los test.
    2. Mediante la pestaña de errores del proyecto, donde tiene su apartado específico.
    3. Mediante una señal de error en el código del test que ha fallado, donde devuelve el error de JUnit (fallo de Assert…).

Los pasos par instalarlo en Eclipse son muy sencillos, son los siguientes (perdón por los colores del Eclipse Luna con el tema Dark ^_^):

1. Vamos al Eclipse Marketplace (Menú Help > Eclipse Market Place…).

2. En la caja Find escribimos “Infinitest” y esperamos al resultado.

Screenshot from 2014-11-22 09:41:28

3. Aceptamos condiciones de instalación (y advertencias de contenido no firmado ^_^)

4. Reiniciamos el IDE.

Cuando iniciamos de nuevo Eclipse y si no se ha ejecutado nunca, aparecerá un nuevo control en forma de barra en la zona inferior izquierda de la pantalla, que indica que Infinitest está esperando acciones.

Screenshot from 2014-11-22 09:44:27

He creado un proyecto muy sencillo para probar su funcionamiento. Sea el siguiente test que requiere un contador que cuente palabras y devuelva el valor de tipo int “6” al ejecutarse:

test

Si seguimos el paradigma TDD, debemos escribir el código mínimo que supere el test. Podría ser este.

test

 

Sí, si te lo estás preguntando, solamente devuelve un 6 sin hacer operaciones porque es lo que el test ha pedido. Se trata de cumplir el test con el código mínimo. Si esperabas la funcionalidad de que contase el número de palabras, se debería haber especificado en el test poniendo más casos.

Volviendo al CTTD con Infinitest. En el momento que salvamos el fichero de código que pretendo cumplir el test, Infinitest ejecuta todos los test del proyecto para detectar las dependencias código-test. Ahora cada vez que salvemos ejecutará los necesarios. El resultado de la ejecución se muestra en la zona inferior izquierda:

Screenshot from 2014-11-22 10:17:53

Y como nuestro código es adecuado, ¡tenemos una bandera verde! Podemos añadir otro test para llegar donde queremos.

test3

Nada más salvar el fichero del test (un cmd+s o ctrl+s), podemos ver que aparece una señal de error en Eclipse (la bombilla con una equis en la línea 13). El indicador de Infinitest también los avisa.

test4

Si vamos a la pestaña “Problems” podemos ver las causas:

TEST5

Obviamente el problema está en que nuestro código simplemente devuelve un número 6 y no cumple el segundo test. Modificamos el código de nuestra clase para que cuente las palabras del texto pasado por parámetro. Se me ha ocurrido hacer un split y contar el vector resultante:

Test6

Y nada más salvar el código de nuestra clase, el test correspondiente se ha ejecutado en segundo plano. Los fallos del test desaparece también.

Screenshot from 2014-11-22 10:35:03

Como habéis podido ver, en este proceso tendría que haber ejecutado el test unitario al menos 4 veces si siempre hubiera acertado con la solución a los test a la primera. Asi que he ahorrado un tiempo y distracciones, y he podido concentrarme en escribir el código adecuado.

Por supuesto, el hecho de disponer de una herramienta para hacer CTTD no sustituye ninguna de las otras partes del TDD, es simplemente una ayuda más para acelerar el proceso. Debemos seguir ejecutando todos los test de forma periódica y debemos seguir utilizando los sistema de integración y generar las builds como siempre

Seguro que cuando lo pruebes será un clásico en tu IDE (o al menos otra herramienta que permita hacer CTTD).

 

Ficheros de configuración externa en aplicación Tomcat y lectura con JNDI de la localización.

Siguiendo la entrada anterior sobre ficheros editables por el usuario que va a manejar (y administrar) la aplicación, podemos localizarlos en un lugar más útil que dentro de las clases de la aplicación (.war que se sobreescribirá en nuevos despliegues).

Podemos colocar los ficheros de configuración en un directorio en el servidor y configurar esta ubicación en el fichero context.xml de Tomcat. De este modo, usando JNDI podremos tener acceso desde el código al lugar indicando en un variable de entorno. Vamos a verlo.

Supongamos que tenemos el fichero con la plantilla que queremos que sea editable por el usuario en /server/myApp/configuracion.txt.

Podemos editar el fichero context.xml de nuestro tomcat para incluir una variable de entorno que apunte al fichero.

<Environment name="ficheroConf" value="/server/myApp/configuracion.txt." type="java.lang.String"/>

El fichero context.xml se encuentra en:

  • $CATALINA_BASE/conf/context.xml para todas las aplicaciones que estén corriendo en el servidor
  • $CATALINA_BASE/conf/[enginename]/[hostname]/myApp.xml donde myApp es el nombre de la aplicación

¿Cómo leemos la variable de entorno? Muy fácil, usando JNDI dentro de nuestra aplicación.

Si estamos usando un contenedor JEE, simplemente tenemos que tomar el contexto inicial:

InitialContext ctx;
String fileName = null;
try {
    ctx = new InitialContext();
    fileName = (String) ctx.lookup("java:comp/env/ficheroConf");
}
catch (NamingException e1) {
    fileName = getClass().getResource(".configuracion.txt").getFile();
    LOG.error(e1);
}

LOG.info("Leyendo configuración desde: " + fileLineZPL);

File labelFile = new File(fileLineZPL);

try {
    ret = FileUtils.readFileToString(labelFile);
} catch (IOException e) {
    LOG.error(e);
}

return ret;

Como se puede ver en el código, se lee la variable usando JNDI y empleando el contexto inicial que nos permite el servidor JEE. Si fallase, o para hacer test sin levantar Tomcat (pero teniendo preparado el fichero de configuración en otro lugar), también se opta por usar getResource como alternativa.

Localización de un fichero (recurso) en el proyecto Java para su lectura

Imagina que tienes que incluir en tu proyecto de Java (de cualquier tipo) un fichero en el que tienes cierta plantilla para que el usuario de la aplicación (más bien el administrador) pueda editar la plantilla y hacer unos cambios. Si ese fichero no es un .properties clásico, lo deberás dejar dentro de un directorio de la aplicación.

Por ejemplo lo podemos dejar en src/main/resources/plantilla.sql

¿Cómo accedemos desde una clase de Java a este fichero para su lectura?

La mejor manera es usar la funcionalidad para encontrar un recurso del ClassLoader de este modo:

URL fileLocation = getClass().getClassLoader().getResource("plantilla.sql");

Con esta instrucción busca en todo el classpath hasta encontrar el fichero. Si el fichero estuviera fuera del classpath podemos anteponer un “.” de modo que sería:

URL fileLocation = getClass().getClassLoader().getResource(".plantilla.sql");

Una vez tenemos la localización, podemos sacar el path completo y usarlo para generar un objeto de la clase File que podamos leer con una librería de Apache FileUtils por ejemplo

File plantillaSQL = new File(fileLocation.getFile());
String plantilla = FileUtils.readFileToString(labelFile);

Proyecto en Eclipse con Jersey(JAX-RS 2.0)+Tomcat+JSON

En los últimos años se pretende llevar más allá la separación entre datos y representación: se está pasando de un modelo en el que la separación se hace en el servidor (con desarrollos MVC) a transferir la responsabilidad de la vista al cliente, con las nuevas “single-page web application” basadas en HTML5.

De este modo se pretende que la comunicación que se lleva a cabo entre el cliente y el servidor sea la mínima posible, siendo datos la información que se transfiere. Los más usados últimamente son los datos en formato JSON, que se adaptan perfectamente a los clientes hechos en JavaScript. Un paradigma de comunicación puede ser por lo tanto un servidor RESTful, tal y como vimos en el ejemplo de AngularJS y CouchDB (que implementa de forma nativa un servidor Web con comunicación RESTful para dar acceso a los datos).

Hay en el mercado diferentes opciones para crear un servidor RESTful con diferentes tecnologías. Al fin y al cabo se trata de implementar un servidor en el puerto 80 (normalmente) que responde al protocolo HTTP y a sus diferentes comandos (GET, POST, HEAD…). Podríamos implementar nosotros mismos uno cualquiera en cualquier lenguaje. La comunicación se realiza a través de diferentes protcolos, como XML, JSON, Texto plano… No pienses que RESTful se emplea para desarrollar aplicaciones Web: también es un buen método para desarrollar la interoperabilidad entre diferentes sistemas.

Dentro de la oferta de Java, existen diferentes opciones, como por ejemplo usar un MVC como Struts2 y añadirle un plug-in para RESTful. Este plugin se encargará de traducir las peticiones HTTP y sus cabeceras a las diferentes acciones que hayamos desarrollado. También existe la opción de usar JAX-RS, que desde Java6 forma parte del estándar J2EE.

JAX-RS es un framework que nos permite desarrollar de una manera sencilla y fiable servicios web de tipo RESTful. Su implementación de referencia es el framework Jersey. Así pues, en este artículo vamos a ver cómo podemos montar en Eclipse un proyecto de base que funcione sobre Tomcat y además la comunicación se lleve a cabo a través de objetos JSON.

Antes de comenzar, hay que destacar que podemos apoyarnos en Maven para todo el proceso. Recomiendo el uso del plugin m2e que ya tratamos en otro artículo del blog (https://mysticalpotato.wordpress.com/2014/01/21/maven-en-eclipse-m2e/).

1. Crear Proyecto Web dinámico con Eclipse y Tomcat 7

Esto no debería ser problema. Como siempre, ir a File->New->Dynamic Web Project

newDynamicProject

Si además en el último paso indicamos que queremos crear el fichero web.xml mucho mejor (aunque posteriormente vamos a sobreescribirlo).

2. Incluir las bibliotecas de Jersey y Jackson

Ahora dos alternativas, dependiendo de si usamos o no Maven:

Si NO usamos Maven

a. Ir a https://jersey.java.net/download.html y descargar el fichero “Jersey JAX-RS 2.0 RI bundle” y descomprimirlo en nuestro disco duro.
b. Copiar las bibliotecas de los tres directorios a WEB-INF/lib (o incluirlas en el proyecto, si es así, tener en cuenta que hay que añadirlas en el deploy).

También debemos instalar Jackson, que es el parser para transformar a JSON las comunicaciones del servidor RESTFUL:

a. Ir a http://wiki.fasterxml.com/JacksonDownload y descargar la última versión
b. Copiar las bibliotecas a WEB-INF/lib (o incluirlas en el proyecto, si es así, tener en cuenta que hay que añadirlas en el deploy).

En el caso de que estemos usando Maven

En primer lugar podemos convertir un proyecto que no tengan Maven en uno que sí lo tenga. En Eclipse con m2e es muy sencillo: pulsamos con el botón auxiliar del ratón en el proyecto, luego en Configure->Convert to Maven Projects

jax1

Una vez tenemos el proyecto convertido a Maven podemos incluir las dependencias en el fichero pom.xml; se puede hacer tanto con la interfaz gráfica de Eclipse como editando el código. Habría que incluir las siguientes:


<dependencies>
 <dependency>
 <groupId>org.glassfish.jersey.containers</groupId>
 <artifactId>jersey-container-servlet</artifactId>
 <version>2.5.1</version>
 </dependency>
 <dependency>
 <groupId>org.glassfish.jersey.core</groupId>
 <artifactId>jersey-client</artifactId>
 <version>2.5.1</version>
 </dependency>
 <dependency>
 <groupId>com.fasterxml.jackson.jaxrs</groupId>
 <artifactId>jackson-jaxrs-json-provider</artifactId>
 <version>2.2.3</version>
 </dependency>
 </dependencies>
 

Las dos primeras dependencias indican que se va a emplearn Jersey versión 2.5.1 (la última cuando se creó este post). El siguiente, com.fasterxml.jackson.jaxrs, es provider de JSON para poder transformar la comunicación RESTful a este protocolo.

3. Crear el web.xml para que la aplicación funcione correctamente en nuestro contenedor de servlets (Tomcat 7 en nuestro caso)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 id="WebApp_ID" version="3.0">
 <display-name>js6</display-name>

<servlet>
 <servlet-name>JAX-RS Servlet</servlet-name>
 <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
 <init-param>
 <param-name>jersey.config.server.provider.packages</param-name>
 <param-value>com.mysticalpotato.JAX</param-value>
 </init-param>
 <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
 <servlet-name>JAX-RS Servlet</servlet-name>
 <url-pattern>/rest/*</url-pattern>
 </servlet-mapping>

<welcome-file-list>
 <welcome-file>index.html</welcome-file>
 <welcome-file>index.htm</welcome-file>
 <welcome-file>index.jsp</welcome-file>
 <welcome-file>default.html</welcome-file>
 <welcome-file>default.htm</welcome-file>
 <welcome-file>default.jsp</welcome-file>
 </welcome-file-list>
</web-app>

¿Qué es importante en este web.xml?

Principalmente que existe un servlet (org.glassfish.jersey.servlet.ServletContainer, solo en el caso de JAX-RS 2) que se encarga de capturar todas las peticiones que le lleguen al subdirectorio “rest” del servidor y que las procesará como RESTful: tendrá en cuenta la URL y las operaciones de la cabecera y las asignará a determinadas clases. El directorio “rest” puede ser cambiado por el que nosotros indiquemos.

Además hay otro parámetro muy interesante, jersey.config.server.provider.packages, que indica en qué paquete están las clases a las que se tiene que mapear las peticiones RESTful. No existe un fichero de asignación como tal, sino que, a través de anotaciones, en cada clase se indica la URL a la que responde cada una, y dentro de ella, qué métodos responden a cada tipo de operaciones y qué resultado o entrada procesan. En el caso del ejemplo está asignado a “com.mysticalpotato.JAX” pero puedes cambiarlo por lo que creas conveniente.

4. Crear una aplicación básica

Una vez tenemos configuradas las bibliotecas y el contenedor de servlets, podemos comenzar a desarrollar nuestro primer servicio:

En primer lugar vamos a crear una sencilla clase de datos, un POJO que contiene tres características de un coche. Lo albergamos en el paquete com.mysticalpotato.data:

package com.mysticalpotato.data;

public class Coche {

 String marca;
 String modelo;
 long potencia;
 public String getMarca() {
 return marca;
 }
 public void setMarca(String marca) {
 this.marca = marca;
 }
 public String getModelo() {
 return modelo;
 }
 public void setModelo(String modelo) {
 this.modelo = modelo;
 }
 public long getPotencia() {
 return potencia;
 }
 public void setPotencia(long potencia) {
 this.potencia = potencia;
 }
}

De este clase implementaremos un objeto que será el que se transforme de modo automático a formato JSON cuando se publique el punto de acceso RESTful;

Creamos un paquete para albergar los servicios RESTful, que coincida con lo indicado en el fichero web.xml como parámetro del servlet RESTful. En el caso de este ejemplo tenemos com.mysticalpotato.JAX.

Dentro vamos a crear la clase “Coches” con el siguiente código:

package com.mysticalpotato.JAX;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import com.mysticalpotato.data.Coche;

@Path("coches")
public class Coches {

@GET
 @Produces(MediaType.APPLICATION_JSON)
 public Coche getIt() {
 Coche c = new Coche();
 c.setMarca("Ferrari");
 c.setModelo("F45");
 c.setPotencia(430);
 return c;
 }
}

Cosas importantes:

  • Se ha declarado “coches” como la URL de acceso a este punto RESTful. Entonces la URL será del tipo http://servidor.com/rest/coches. El “directorio” rest viene de la confijguración del servlet en el web.xml.
  • Cuando se haga una petición de tipo GET (la que se hace cuando se pide una página en un navegador), se accederá al método getIt(). La razón es que hemos indicado esto con la anotación @GET.
  • El tipo de datos de salida será de tipo JSON, y funcionará además porque hemos usado el proveedor Jackson, que se encargará de hacerlo funcionar.

La salida será:

{"marca":"Ferrari","modelo":"F45","potencia":430}

Un aspecto importante: será necesario indica que cuando el proyecto se despliegue en el servidor, también lo hagan las librerías de Maven que se han indicado. Para ello ir a propiedades del proyecto->Deployment Assembly y añadir las dependencias de Maven o de los ficheros si se ha hecho en manual.

Groovy. Un lenguaje de Scripting que se ejecuta en la Java Virtual Machine

Los lenguajes interpretados o script están en claro auge. Son varias las razones. Por una parte al incremento en la potencia y memoria de las máquinas que los ejecutan y la mejora de los motores de ejecución, lo que evita una de las mayores desventajas hasta ahora como era su menor rendimiento que un código compilado. Por otra parte, desde el punto de vista del programador son lenguajes con una sintáxis más relajada ya que son menos rígidos a la hora de establecer el tipado de datos o determinados tipos de estructuras de programación. La interoperabilidad también es uno de sus puntos fuertes, sirviendo como “pegamento” entre diferentes tecnologías. Lenguajes como Perl, Ruby, o Python son una herramienta perfecta en estos días. Y ni que decir tiene del resurgimiento de Javascript, tnato para HTML5 en los navegadores como en la parte del servidor con NodeJS

Los lenguajes de prográmación interpretados requieren un motor de ejecución que va evaluando de forma secuencial sus instrucciones. Dentro de los muchos existentes llaman la atención aquellos que son capaces de correr en la Java Virtual Machine. Nos estamos refiriendo a Scala, Clojure o Groovy. Es precisamente este último sobre el que trata esta entrada.

Groovy es un lenguaje ligero, dinámico, orientado a objetos y especialmente concebido para ser muy productivo (esto es, con pocas líneas de código se pueden hace maravillas). Y sobre todo, corre en la JVM y es compatible con Java. Sí, podemos utilizar código Java dentro de Groovy, así como las librerías de Java. Por decirlo de modo vulgar: podemos hacer todo lo que puede hacer Java y además muchas otras cosas de un modo más fácil. Existe una framework llamado GRails (como Ruby on Rails) para el desarrollo de aplicaciones basado en Groovy.

¿Por qué usar Groovy? Si ya sabes Java puede ser una buena herramienta para todo tipo de desarrollos rápiudos o como complemento al código de Java más complejo que hemos realizado. Por ejemplo, si queremos descargar el código fuente de una URL y salvarlo a disco, en Groovy simplemente son necesarias dos líneas de código:

def contenido = "http://www.rusizate.com".toURL().getText()
new File("forocoches.html").append(contenido)

No creo que sea necesario que te compare con el número interminable de líneas de código que requiere esto en Java. Entre los imports, la definición de una clase básica, su método main, establecer la conexión, abrir los streams, comunicarlos con un fichero y descargar en un buffer byte a byte…

De este modo podemos hacer muchas operaciones rápidas y muy útiles, además de utilizar Groovy para ejecutar el script simplemente, sin necesidad de generar los .class y luego ejecutarlos. Todo va directo. Por ejemplo, para listar una select por pantalla de una base de datos SQL Server y guardarlo en base de datos:

import groovy.sql.Sql

sql = Sql.newInstance("jdbc:sqlserver://servidor:1433;databaseName=baseDatos", "sa", "password","com.microsoft.sqlserver.jdbc.SQLServerDriver");
def salida=""
sql.eachRow("select * from tabla", {salida+=" ${it.PK1} - ${it.NOMBRE}" + System.getProperty("line.separator")})

new File("d:\\salida.txt") &lt;&lt;salida
println salida

También es tremendamente útil para probar nuestro código Java. El desarrollo TDD (Test Driven Development) se está demostrando muy eficaz en la creación de todo tipo de aplicaciones. Groovy, al poder interactuar con nuestro código Java (o cualquier .jar que utilicemos) nos puede servir para probar nurestro código o desarrollar test de forma muy rápida. O también integrarnos con otros sistemas.

En definitiva Groovy es una buena herramienta de scripting si estás habituado a Java. Y manejar un lenguaje de script hoy en día es fundamental para poder interconectar multitud de sistemas o simplemente ser productivos en aquellas tareas que son secundarias. Y todo esto sin olvidar que es un lenguaje orientado a objetos y que cada vez hay más de manda de profesionales con conocimientos de Grails.

Explicar el lenguaje entero llevaría bastante tiempo. Si sabes Java te resultara fácil porque siempre que te veas atascado podrás recurrir a tus conocimientos de Java. No obstante, cuando empieces a ver la potencia y sencillez de la sintáxis propia de Groovy rápidamente verás cómo querras saber más y más instrucciones nativas que sustituyen a la tediosa y estricta sintáxis de Java.

Existen mutlitud de páginas y libros sobre Groovy y algunos especializados en enseñar a los que ya saben programar en Java. Puedes probar con este si lo deseas: http://www.amazon.es/Programming-Groovy-Productivity-Developer-Programmers/dp/1937785300/ref=sr_1_fkmr1_3?ie=UTF8&qid=1390724841&sr=8-3-fkmr1

¿Cómo puedo empezar con Groovy?

Es muy sencillo, solamente tienes que tener una máquina virtual de Java (JVM) instalada en tu equipo, y descargar Groovy desde su página principal: http://groovy.codehaus.org/

Una vez descomprimido tienes que establecer como variable del sistema GROOVY_HOME el directorio en el que está ubicado.

En GROOVY_HOME/bin tienes los ejecutables. Dentro de todos los que aparecen hay dos interesantes: groovy.bat con el que ejecutar los scripts de Groovy y groovy-console.bat para lanzar una consola en la que poder programar los scripts y ejecutarlos (Ctr+R para RUN y Ctrl+W para limpiar pantalla).

Así puedes comenzar con el ejemplo típico:

println "Hola Mundo"

O algo más complejo

println "Hola mundo"

def vector=[]
def texto
1.upto(3)
{
texto = it + " - Hola Mundo"
vector&lt;&lt;texto
}

println vector.join(" | ")

Con teste código hemos definido un ArrayList en el que se van introduciendo los valores de “texto” en cada momento. La variable “it” representa el valor del contador y el “add” clásico para introducir valores a un vector se puede hacer mediante el operador “<<“. Finalmente se muestran por pantalla todos los elementos del vector, separados mediante esta cadena ” | “. Sencillo, ¿no?

Para ejecutarlo simplemente presiona Ctrl+R y ya estará corriendo. Mucho más rápido que usar Java.

Si estás acostumbrado a Java echarás de menos el autocompletar que tienen los editores como Netbeans o Eclipse. No te precupes porque existe un plugin para que desarrolloes Groovy en Eclipse, con todas las ventajas que esto conlleva (entre ellas la del autocomplete).

Accede a http://groovy.codehaus.org/Eclipse+Plugin e instalar Groovy-Eclipse eligiendo la URL adecuada para tu versión. Ya sabés… en Eclipse ir a Help->Install new Software… Si tenéis ya instalado el M2E (Maven para Eclipse), es probable que exista un conflicto que dificulte la instalación.

Una vez instalado el plugin, se crea un archivo nuevo de tipo Groovy Class y se puede programar. Recordar que se tiene que correr como Groovy, no como servidor o aplicación Java.

Si estáis acostumbrados a otros editores, como por ejemplo del magnífico Sublime Text 2, también es fácil ponerse a trabajar con Groovy. Simplemente salvamos el fichero como .groovy y la sintáxis debería cambiar. Para ejecutarlo vamos al menú Tools>Build System>New Build System. Se abrirá una ventana nueva donde podremos pegar el siguiente código:

{ "cmd": ["F:\\groovy-2.2.1\\bin\\groovy.bat", "$file"] }

Donde F://… es la ruta donde yo tengo mi GROOVY_HOME. La tuya probablemente sea otra.

Ahora simplemente presionando Ctrl+B podrás correr los scripts de Groovy en Sublime Text 2.

Un último apunte que me costó trabajo encontrar: cuando tengamos que utilizar otras bibliotecas como la de base de datos por ejemplo para acceder a SQL, necesitaremos dejar los ficheros .jar en algún lugar accesible. El lugar en el que funciona es el del usuario/.groovy/lib (en mi caso para W7 es C:\Users\mysticalpotato\.groovy\lib). Copiando ahí los .jar no habrá problemas de clases no encontradas.

El ejemplo

Una vez ya estamos con toda la información vamos a ver un pequeño ejemplo de integración de una librería de Java dentro de Groovy y de cómo es de sencillo utilizar Groovy para tareas que en Java nos llevarían decenas de líneas de código.

El ejemplo consiste en descargar a un fichero las portadas de los subforos del conocido foro Forocoches (no un foro de coches, sino Forocoches) y mostrar los asuntos de los mensajes que hay en portada gracias a la libería jsoup (http://jsoup.org/). Está basado en esta magnífica serie de post sobre cómo hacer scraping web con Groovy (http://imediava.wordpress.com/2011/08/18/web-scraping-with-groovy-1-of-3/). El código Groovy es el siguiente:

import org.jsoup.nodes.Document
import org.jsoup.Jsoup

def tamanho = -1
def contenido
def listado_foros_validos = []
def result

def fichero = new File("forocoches.html")
def contador_mensajes = 0

0.upto(60)
{
contenido = "http://www.forocoches.com/foro/forumdisplay.php?f=$it".toURL().getText()

tamanho=contenido.length()/1024
if (!contenido.contains("Foro especificado"))
{
println "Tamaño $it: $tamanho kb | "
listado_foros_validos.add(it)

fichero.append(contenido)

Document doc = Jsoup.parse(contenido)
results = doc.select(".page ul")[1]
results?.select("li a")?.each()
{
println it.text()
contador_mensajes++
};

}
}

println "Foros validos: " + listado_foros_validos
println "Mensajes totales: " + contador_mensajes

Algunas de las peculiaridades que merece la pena comentar:

  • La librería jsoup (http://jsoup.org/) nos permite parsear una cadena de texto (o una URL) y analizarla utilizando selectores tipo JQuery. Es una librería excelente que recomiendo dominar. Se tiene que descargar el fichero .jar de esta librería y dejarlo en nuestra home/.groovy/lib para que Groovy tenga acceso. Vemos cómo se hace el import de librerías en Groovy, similar a Java.
  • Jugamos con el modo de identificar los subforos en la URL. El parámetro “f” seguido de un número entre 1 y 60 nos va a indicar el subforo correspondiente. Si algún número nos lleva a un subforo inválido lo indica con la cadena de texto “Foro especificado”.
  • Es muy fácil descargar el código de una página mediante String.toURL().getText()
  • Añadimos a un vector llamado “listado_foros_validos” los índices que indican suforos válidos.
  • Escribimos en un fichero con append(String).
  • de Jsoup podemos destacar el parse de la cadena de texto y la operacion “select” que recibe por parámetro unos selectores tipo jQuery
  • El operador “?” es destacable. Es equivalente a if(elemento!=null){} Es decir, que result?.select hace algo así como “si result no es nulo entonces haz la instrucción select”.
  • Podemos recorrer un objeto de tipo array con .each(), siendo it el elemento que se corresponde en cada iteración.

En definitiva, Groovy es un lenguaje de scripting que merece la pena conocer si estás familiarizado con Java. Es muy potente gracias a su sintáxis altamente productiva y la posibilidad de interactuar con Java.

Maven en Eclipse: m2e

Una de las cosas que menos me gusta a la hora de empezar un proyecto nuevo es tener que comenzar desde cero a montar todas la infraestructura para poder comenzar. A pesar de que Eclipse tiene diversas plantillas, éstas son muy genéricas y hay que complementarlas con librerías y servidores, lo que nos puede llevar un buen rato hasta que comenzamos a poder empezar a ser productivos. Por ejemplo si queremos un proyecto que lleve struts2 con acceso JPA a base de datos, tenemos que ir a proyecto java web y complementar las librerías.

El punto ideal de comienzo de un proyecto sería disponer de un “Hola Mundo” básico sobre el cual empezar a programar, saltándonos la configuración previa. Afortunadamente en el mundo Java existe una herramienta llamada Maven que facilita el ciclo de vida de una aplicación, desde su creación (aspecto del que va este post) hasta el testing o el deploy. En este post solamente vamos a ver cómo aprovechar una pequeña parte de su potencial para facilitarlos el inicio de un proyecto.

Maven es una herramienta de Apache que puede ser descargada en http://maven.apache.org/ y que se puede encontrar una introducción a su uso en http://maven.apache.org/users/index.html (recomiendo el apartado http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html para un rápido vistazo práctico a su potencial). Su funcionamiento para la creación está basado en los “Archetypes” que son una especie de plantillas que utilizaremos para crear nuestro proyectos y que contiene una descripción de las librerías y otras dependencias, así como unos ficheros básicos que contiene el “hola mundo” que necesitamos para comenzar.

Mediante Maven podemos “instanciar” un archetype de nuestro gusto de los múltiples que hay por Internet, como por ejemplo de http://search.maven.org/ o de http://mvnrepository.com/ . Hay cientos de ellos asi que es complicado no encontrar uno que se adapte a nuestras necesidades. Maven descarga el archetype y crea en el directorio que le indiquemos una implementación del proyecto. Además se descarga las bibliotecas .jar en un lugar común en nuestro ordenador y establece las dependencias para que simplemente ejecutemos.

Como se trata de una herramienta básica que muchos otros programas utilizan y además es susceptible de automatizar (sobre todo por las otras etapas del ciclo de vida en las que es de gran ayuda), no tiene una interfaz gráfica. Esto tiene sus ventajas e inconvenientes. En este post vamos a ver cómo la podemos integrar dentro de Maven para que los usuarios que están más acostumbrados a usar eclipse, puedan usar las ventajas de esta herramienta. Para ello existe el plugin m2e para Eclipse, así como su integración en WTP (Web Tools Platform) de Eclipse. Este plugin ya incorpora una edición embebida de Maven para que no tengamos que hacer nada

Pasos para ponerlo en práctica:

1. Instalar los plugins de eclipse m2e y m2e-wtp, que integra maven con el WTP (Web Tools Platform) de eclipse:

  • Ir a Help->Install new Software e introducir la siguiente URL: http://download.eclipse.org/m2e-wtp/releases/juno/ (o la distribución de Eclipse que estemos usando – Kepler, Galileo…-)
  • Elegir el plugin m2e y el m2e-wtp normal (no el SDK, aunque podemos instalarlo si queremos)
  • Reiniciar Eclipse para finalizar la instalación

(En la página oficial de los plugins hay un excelente video de poco más de un minuto http://www.eclipse.org/m2e-wtp/)

2. Para crear un repositorio:

  • Crear un proyecto nuevo (File->New->Other o Ctrl+N)
  • En la caja de elección del wizard, escribir Maven para localizar los proyectos de Maven
  • Elegir “Maven Project”
  • Usar el default workspace de Eclipse (para que cree el proyecto en nuestro workspace, que suele ser lo más habitual).
  • En la ventana de elección del archetype, pinchar en Configure, puesto que no están los que buscamos (necesitamos localizar un Archetype de Struts2).
  • En la ventana de configuración de Archetypes, pulsar sobre “Add Remote Catalog” y añadir un nuevo repositorio con esta URL: http://repo1.maven.org/maven2/archetype-catalog.xml
  • Elegir como fuente el nuevo catálogo (yo lo he llamado “Maven General” pero puedes llamarlo como quieras)
  • Pinchar sobre struts2-archetype-blank (que es un archetype de un proyecto struts2 en blanco. Puedes elegir el que quieras).
  • En la siguiente ventana, completar los datos del proyecto que amos a crear: Group ID para el grupo al que pertenece el proyecto; Artifact ID para designar el proyecto y Package para nombrar el paquete base que usaremos.
  • Pulsamos en finalizar para acabar con el wizard de creación.

Ahora esperamos unos instantes para que Maven descargue todas las librerías y dependencias que están declaradas en el archetype, y para que cree los ficheros básicos (algunas acciones de Struts2, JSP, los xml de configuración de la aplicación Web…)

Al final tendremos un proyecto basado en el Archetype elegido. Podremos ver que:

  • El proyecto se ha creado en nuestro workspace y que ya tiene una estructura completa creada, con las dependencias de struts2 necesarias, además de una aplicación de ejemplo con acciones básicas y un struts.xml
  • Las dependencias (los .jar) ahora se encuentran en nuestro ordenador en nuestro directorio personal de nuestro sistema operativo /.m2/repository
  • Podemos tratar el proyecto como si de un proyecto web de Eclipse se tratara. Esto es posible gracias al plugin m2e-wtp.

Desafortunadamente puede surgir una serie de problemas derivados del uso del plugin m2e para Eclipse, que podremos resolver con ayuda de StackOverflow en su mayor parte. Aquí van alguno de los problemas que he experimentado, aunque todos ellos se han podido resolver con no mucho trabajo:

  • El problema persistente del fichero Missing artifact com.sun:tools:jar:1.5.0:system pom.xml que es un fichero que lleva el JRE pero que no es capaz de encontrar. Esta biblioteca (tools.jar) forma parte de la instalación del JDK pero no del JRE. Si tenemos el JRE instalado y eclipse está corriendo con la máquina virtual del JRE y no del JDK puede sucedernos este error, puesto que no es capac de encontrar la biblioteca tools.jar. Se soluciona de esta forma:
    •  editando el fichero eclipse.ini e incluyendo justo antes de de -vmargs la sentencia: vm “C:\Program Files\Java\jdk1.6.0_37\bin\javaw.exe”. (o donde se tenga el JDK instalado.
    •  usando el JDK como entorno de ejecución del proyecto (y no el JRE).
    •  por último haciendo un clean del proyecto seguido de un build para que coja los cambios.
  •  Descarga incorrecta de bibliotecas. Es algo que en Maven en modo comando es fácil de detectar puesto que avisa de que el hash del fichero no coincide con el proporcionado, pero en Eclipse debemos esperar a un build del proyecto. De este modo recibiremos errores de clases no encontradas o similar. La razón es que el fichero .jar está corrupto y no puede extraerse la información. La solución:
    • Ir al repositorio de bibliotecas que hay en nuestro perfil de usuario (en mi caso: C:\Users\mysticalpotato\.m2\repository) y localizar el .jar. Se renombrar o elimina y se actualiza el proyecto con Maven (botón auxiliar sobre el proyecto, Maven->Update Project) para que se vuelva a bajar todas las bibliotecas que no están. Si hay suerte se bajarán las correctas, sino habrá que insistir

Subversive SVN en Eclipse

Sirva este post como recordatorio para algo que tengo que hacer cada cierto tiempo, que es instalar un cliente de SVN en Eclipse, y en concreto Subversive, que es el que suelo utilizar. Está basado en una respuesta de http://stackoverflow.com/questions/14268003/subversive-svn-connectors-does-not-appear-in-eclipse-juno

En primer lugar tenemos que tener descargada la versión correspondiente de Eclipse. En este caso utilizaré la última versión disponible en la fecha de creación de este post: Kepler. La puedes encontrar http://www.eclipse.org/kepler/ . Usaré la versión para desarrollar J2EE.

Una vez descargado y ejecutado Eclipse, seguimos estos pasos:

  1. Descargar Subversive desde Help->Eclipse MarketPlace. Allí buscamos “Subversive” y aparecerá un producto llamado “Subversive – SVN Team Provider”. Pinchamos sobre install y seguimos los pasos.
  2. Descargar el Subversive SVN Connector. Para ello vamos a Help->Install new Software. En la caja “Work With” introducimos la URL: http://community.polarion.com/projects/subversive/download/eclipse/3.0/juno-site/ (para Juno) o http://community.polarion.com/projects/subversive/download/eclipse/3.0/kepler-site/ (para Kepler). Elegimos Subversive SVN Connector. Instalamos normalmente.

Ir a la vista SVN Repository Exploring y poner a punto nuestro repositorio SVN con el que vamos a trabajar.