jueves, 28 de mayo de 2009

Obtener la SQL generada por una Criteria de Hibernate en runtime

Recientemente he necesitado obtener la consulta SQL que genera una Criteria de Hibernate en tiempo de ejecución. La primera opción, obviamente, es leer la documentación de Hibernate Criteria, pero Hibernate no posee ninguna funcionalidad para obtener la SQL en su clase Criteria, ni en las clases relacionadas. Esto me resulto extraño, dado que con Hibernate Criteria se pueden volcar las consultas al log usando por ejemplo log4j, para ello hay que:
  • Asignar el valor "true" a la propiedad "hibernate.show_sql" en el sessionFactory.
  • Añadir en el fichero de configuración del log4j dos appenders:
    1. org.hibernate.SQL = DEBUG --> Para ver las consultas.
    2. org.hibernate.type = TRACE --> Para ver los valores de los parámetros.
Dado que la información está almacenada dentro de la Criteria, tan solo es necesario "sacarla", y para ello usaremos la introspección de Java. El código para obtener la consulta SQL con sus parámetros es el siguiente:

Como vemos en el código usamos la introspección para inspeccionar el contenido de algunos atributos privados del Loader y así obtener la información que queremos.

Tengo que decir que esta forma de utilizar las criterias e Hibernate no es muy ortodoxa, y que en caso de usarse debe hacerse de forma muy controlada, no debe ser una práctica habitual, ya que nada nos asegura el correcto funcionamiento de este tipo de artificios. Eso si por una necesidad imperiosa necesitamos obtener la consulta SQL que genera en tiempo de ejecución es un alternativa.

miércoles, 20 de mayo de 2009

Introducción a Flex Profiler

Hoy quiero hablarles del "Flex Profiler", una herramienta incluida en el Flex Builder que nos permite realizar sesiones de profiling (para optimizar el rendimiento y el uso de recursos).

Para utilizarlo tan sólo debemos crearnos un perfil de "profile", esto se realiza de la misma forma que un perfil para ejecutar o para depurar la aplicación. Tan solo debemos picar en el botón teniendo seleccionado el proyecto o bien picando en el mismo botón en la opcion otros. Al hacer esto nos mostrara la pantalla de configuracion del perfil.


Como vemos en la pantalla podemos seleccionar el proyecto, el fichero principal del proyecto (el que contiene el tag Application) y las URLs que se usarán para lanzar la aplicación. Ahora ya podemos lanzar la sesión de profiling desde el boton profile. Al lanzarlo se nos abrirá la perspectiva "Flex Profiling" mostrandonos la pantalla de conexión.

Desde dicha pantalla podemos seleccionar si queremos ejecutar el profiling de memoria, de rendimiento o de ambos. Asimismo, para el profiling de memoria podemos indicar:
  • Si queremos ver los objetos vivos en memoria ("watch live memory data"), que nos muestra el panel "Live Objects" con información de que clases se han instanciado, cuantas instancias existen, la memoria que consume etc.
  • Si queremos generar la traza de asignación de los objetos ("Generate object allocation stacktraces"), que capturará la traza cada vez que se genere un objeto. Tenemos que tener mucho cuidado con esta opcion ya que puede ralentizar el profiler y usar mucha mas memoria.
Es mejor fijarnos ciertos objetivos en cada sesion y no tratar de mejorar el rendimiento y el uso de memoria en la misma sesión.

Garbage Collector
Antes de meternos en harina con el profiling de la memoria, tenemos que entender como funciona el garbage collector de la máquina Flash Player. El garbage collector se basa fundamentalmente en dos técnicas el "Reference Counting" y el "Mark and Sweep".

El "reference counting" basicamente consiste en que cada objeto mantiene un contador de referencias, cada vez que un objeto hace referencia a otro se incrementa el contador de referencia del objeto apuntado. Cuando el contador de referencias es cero el objeto puede ser eliminado. El reference counting presenta un problema serio, y es que si se forma una referencia circular (por ejemplo: A apunta a B y B apunta a A) el objeto nunca será liberado. En el caso concreto de Flex, debemos tener mucho cuidado con esto ya que es muy probable que creamos que un objeto no esta siendo referenciado por nadie y aun así tenga referencias, en este caso debemos echarle un ojo a los listener que pueda tener asociados el objeto, una buena precaución es definir siempre los listeners como weak references, que crean la referencia pero no incrementan el contador de referencias.

El "Mark and Sweep" es una técnica de recolección en la que cuando el garbage collector realiza una pasada (recorriendo el arbol de referencias de los objetos) , comprueba si el objeto puede ser liberado (contador de referencias a cero) si es así lo marca y a su vez, en la misma pasada, si el objeto esta marcado lo elimina.

Otra cosa a tener en cuenta es la frecuencia con la que se ejecuta el garbage collector, cosa que es impredecible, ya que en mi opinión se ejecuta cuando le parece. En teoría, hay un sofisticado algoritmo, que comprueba cuando debe ejecutarse el garbage collector, que se ejecuta cuando se asigna memoria, pero no he encontrado a nadie que lo haya sabido explicar XD.

Profiling de Memoria
Empezaremos con una sesión para mejorar el uso de la memoria. Es muy importante realizar estas sesiones ya que en ellas podremos detectar posibles "memory leaks" (fugas de memoria, es decir memoria que se asigna pero que nunca se recupera). Por lo general para esta sesión, suelo activar la opcion "watch live memory data". Veremos esta pantalla:

Arriba a la izquierda se muestra la pestaña con los datos del profile y los datos guardados. Tenemos varios botones que nos permiten forzar la ejecución del garbage collector, tomar una instantanea de la memoria, etc. (ya iremos hablando de los botones según los usemos).

Arriba a la derecha se muestra una gráfica con el consumo de memoria, donde se ve el consumo de memoria actual y los picos de memoria.

Abajo tenemos la pantalla de "Live Objeccts", con información de que clases se han instanciado, cuantas instancias existen, la memoria que consume. Tenemos que tener que también muestra datos acumulativos ("cumulative instances" y "cumulative memory") y que eston son la suma total de todo durante la ejecución de la aplicación.

Para realizar el profiling debemos tomar una o varias "memory snapshots" en momentos determinados en los que la aplicación haya ejecutado cierta funcionalidad que queremos comprobar. Comparando dichas instantaneas de la memoria podemos identificar instancias de objetos que no se hayan eliminado cuando deberían haberse eliminado. Las snapshots cuando se toman van apareciendo en la pestaña "Profile" (arriba a la izquierda). con un doble click en la snapshot nos muestra la pestaña "Memory Snapshot" , en la que veremos la informacion de los objetos y sus referencias, con doble click ira a la pestaña "Object References", donde vemos las referencias del objeto. De esta forma podemos ir navegando por los objetos para identificar con quien se relaciona y ver porque no ha sido eliminado por el garbage collector.

Profiling de rendimiento
En segundo lugar podemos ejecutar una sesión de profiling para comprobar el rendimiento. en este caso Flex Profiler nos mostrará una pantalla en la que podemos ver el número de funciones y/o procedimientos que se han ejecutado, el número de llamadas, el tiempo que ha tardado y su media.

Con esta información podemos detectar secciones del código que puedan suponer un cuello de botella y que estén ralentizando la aplicación. Por tanto podremos optimizar dichas secciones para mejorar su rendimiento, en este caso la mejora la mediremos por el tiempo que tarde el método. Sobra decir, que es importante fijarse tanto en los procesos que tardan mucho en ejecutarse como en aquellos proceso que se ejecutan muchas veces.

Bueno, creo que ya es bastante información para asimilarla de una sola vez así, que lo voy dejando por hoy para que vayais digiriendolo.

P.D: podemos encontrar mucha información sobre esto en el sitio web de adobe (aqui).
Saludos.

sábado, 9 de mayo de 2009

Noticias de Spring

Hoy tenemos una ración de noticias sobre Spring:

En primer lugar, tenemos el anuncio de la primera Release Candidate de "Spring BlazeDS Integration", podemos verlo aquí. Parece que el proyecto va por buen camino, ya hace poco hablabamos de la milestone 2. En esta "release candidate", a parte de corregir ciertos bugs, se han añadido ciertas funcionalidades muy interesantes:
  • Configuración basada en anotaciones para los destinos remotos.
  • Añade numerosas opciones para personalizar los hooks para cosas tales como la traducción de excepciones o añadir adaptadores de terceras partes. Todo aquel que haya tenido que lidiar con el BlazeDS sabrá apreciar esto, ya que la serialización/deserialización de algunos objetos Java a Actionscript y viceversa puede dar problemas. Asimismo, el tratamiento de excepciones requería de cierta lógica adicional para crear un MesasgeException que encapsulara la excepción Java. Aún no lo he probado, pero parece que simplificar bastante este proceso.
  • Integración completa con el servicio de mensajes de BlazeDS, incluyendo soporte para AMF, JMS y la interacción con transportes de mensaje de Spring. El servicio de mensajería permite la comunicación entre clientes, sin tener que codificar nada en el servidor, dicho servicio de mensajería se basa en el modelo publisher-subscriber, en el que el "message service" actúa como enrutador para ambos clientes Flex y JMS.
La segunda noticia de hoy es la liberación de "SpringSource Tool Suite" (STS), cumpliendo la promesa de Rod Johnson en el "SpringOne Europe". SpringSource Tool Suite es un IDE desarrollado sobre eclipse para desarrollo de aplicaciones con Spring, provee un completo conjunto de herramientas para facilitar el desarrollo de aplicaciones que se ejecuten sobre la mayoría de servidores de aplicaciones (como Apache Tomcat, IBM WebSphere, Oracle WebLogic, JBoss, SpringSource tc Server y SpringSource dm Server).

De entre todas las características y herramientas que ofrece, la que más me ha llamado la atención es la "orientación a tareas" que le han dado al desarrollo. Incluyendo una interfaz de Mylyn, en la que se muestran tareas, recursos abiertos, etc.

Podemos ver más información y descargar la suite aquí. También podemos ver en el blog de Christian Dupuis el listado de características de STS.

domingo, 3 de mayo de 2009

Plugin de Jetty para Maven 2

Usando Maven 2 tenemos la opción de usar este plugin que nos permite ejecutar nuestra aplicación web en un servidor Jetty de forma simple, con las "metas" (goals) run y/o run war. Un servidor Jetty es un servidor HTTP y contenedor de Servlets, mucho más ligero que otros servidores (Tomcat, JBoss, etc) lo que hace que sea ideal para pequeñas aplicaciones y entornos de desarrollo.

La meta run compilará el proyecto y lo ejecutará desde la carpeta que contiene los ficheros compilados, mientras que la meta run-war empaquetará el proyecto en un war y lo ejecutará. Por defecto el jetty se ejecutara en el puerto 8080 con el contexto app/.

Configuración
Podemos configurar algunos parámetros opcionales:
  • port: Puerto que usará el servidor jetty, valor por defecto 8080 (opcional).
  • contextPathSpec: El contexto de la aplicación web, por defecto /app (opcional).
  • webApp: Localización del archivo war, por defecto $project.build.directory/$project.build.finalName.war. Podemos definir el finalName en el tag build del pom (opcional).
  • jettyConfig: La localización del fichero XML de configuración del Jetty, sobreescribirá el resto de parámetros. (opcional).
Para usar este plugin tan sólo debemos añadir en el pom lo siguiente:

Como vemos en el fichero pom.xml de ejemplo hemos definido que el war que genera tenga el nombre fraguaDigitalExample.war. Asimismo, se ha configurado el servidor jetty para que arranque en el contexto fraguaDigital.

Para Arancar el servidor y así poder probar nuetra aplciación, tan solo debemos ejecutar el comando:
mvn jetty:run
o
mvn jetty:run-war

Si arrancamos el naveagdor y vamos a la URL http://localhost:// (en nuestro ejemplo http://localhost:8080/fraguaDigital/) deberíamos ver la aplicación web.