Latest Entries »

Ha pasado algo más de un año desde la última entrada, pero hemos vuelto con las pilas recargadas. A ver lo que me dura esta vez.
En el último post hablé sobre la seguridad en Symfony y lo desastroso que puede ser una mala configuración. Recordemos que si dejabamos expuesto la carpeta app de un proyecto en Symfony2, podiamos dejar accesible el fichero parameters.yml dejando expuesta las credenciales de la base de datos. Dejar  esto en un servidor con el proyecto accesible desde internet, es invitar a que los malvados nos hagan maldades.

A fecha de hoy, y buscando un poco en Google con el siguiente dork: inurl:app/config/parameters.yml te puedes encontrar varios proyectos con este fichero abierto para todos los públicos.
Y en algunos, no solo te encuentras las credenciales de la base de datos, sino también el usuario y contraseña de una cuenta de correo, (de gmail por ejemplo) si tienen configurado el mailer.

parameters.yml real

Ejemplo de un parameters.yml filtrado

Viendo esto, vamos a repasar las medidas de seguridad para evitar esta fuga de información:

  1. Lo más importante, intenta no dejar publicada la carpeta app. Es el fallo más grande.
  2. Si no queda otro remedio, asegurate que los ficheros .htaccess que vienen con la carpeta estén funcionando, puede que tengamos configurado apache para que no nos deje sobreescribir las directicas de seguridad necesarias.
  3. A lo mejor sería interesante incluir alguna directiva que denegara el acceso a través de web de los ficheros .yml.
  4. Si tenemos el proyecto en un repositorio git, es importantisimo poner en el .gitignore el parameters.yml. Mejor configurarlo 30 veces en producción que tener una sola fuga de información

Con todo esto en cuenta, se nos puede dar la situación de que no quede más remedio que publicar la carpeta app accidentalmente. Pero si hemos seguido los anterioes consejos,
no deberiamos de tener tantos problemas ya que hemos protegido los ficheros yml. Pero creernos que estamos a salvo sería un error. En Symfony2 tenemos la carpeta app/cache
en la que se almacenan los compilados de las plantillas y otros recursos del proyecto. Esta carpeta no suele estar protegida por ningún .htacces, de forma que sus documentos serían accesibles.
Dentro de ella encontramos el fichero appProdDebugProjectContainer.xml donde encontraremos lo mismo que hay en parameters.yml, pero no solo eso, también información jugosa como los bundles que se utilizan en el proyecto, que rutas están protegidas y mediante que roles,etc.

appDevDebugProjectContainer.xml

Fichero appDevDebugProjectContainer.xml publicado

De modo que hay que asegurarse de proteger también esta carpeta.

Conclusión, NO dejeis publicado el directorio app. Os ahorrareis muchos dolores de cabeza. Y tened cuidado con las carpetas que dejais accesible al público, sean del framework que sean.

Hoy, he visto este post “Fuga de información en Symfony al chequear requisitos” y me he preocupado al instante, ya que trabajo con este framework y tengo varios proyectos con él. Así que tras realizar un breve análisis de lo que explica en el post, he llegado a la conclusión que esas fugas son producidas por una mala configuración al subirlo al servidor web. Voy a explicar un poco mejor la organización de carpetas y los posibles fallos de configuración que podrían crear este error.

Estructura de carpetas en symfony

Estructura de carpetas en symfony

La imagen anterior muestra la estructura básica de un proyecto en Symfony2. Nos vamos a centrar en dos carpetas. La carpeta web es la parte pública del proyecto, donde tenemos el controlador principal (punto de entrada de todas las peticiones) y todos los recursos estátitcos que utilizarán nuestras páginas (imágenes, css, javascript, etc). Por otra parte, tenemos la carpeta app ,donde se guarda toda la configuración de nuestro proyecto y el archivo check.php. Según la filosofía de seguridad de Symfony la carpeta app NUNCA debería de ser accesible a través del servidor web, si eso ocurriera, sería desastroso ya que ahí tenemos contraseñas en texto plano, logs, etc. Así que cuando publiquemos un proyecto, siempre debermos dejar visible SOLO la carpeta web, para evitar problemas.  Si por desgracia hay que publicar la carpeta principal del proyecto, en principio no habría problema ya que por defecto todos los directorios críticos vienen protegidos mediante un archivo .htaccess con el siguiente contenido:


<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>

Por lo que es importante que nuestro apache permita sobreescribir estas directivas. Por que si no, tendríamos un problema mucho mayor que acceder al fichero check.php.

Fuga de Parameters.yml

Un ejemplo de lo que puede ocurrir con una mala configuración de Apache

Visto todo esto, he caido de que hay otro punto de fuga de información importante. Dentro del directorio web, tenemos el archivo app.php que es el controlador principal, el punto de entrada de todas las peticiones. También tenemos el fichero app_dev.php, también controlador principal pero que nos permite utilizar el entorno de desarrollo. Este entorno nos suele dar varias ventajas cuando estamos desarrollando y depurando un proyecto, una de ellas es la barra de “profiler” que nos permite hacer un seguimiendo de muchisima información.

El profiler en accion

El profiler en accion

Si se accede a esta información en producción, podrian obtener todas las rutas de nuestro proyecto, acceso al phpinfo, las consultas sql que utilicen nuestras páginas, bundles usados por el proyecto y la versión de symfony. Supongo que me dejaré alguna cosa en el tintero, pero cómo veis no es moco de pavo. Así que es importante no subir este fichero a los servidores de producción o modificarlos para incluir alguna restricción. Por defecto, incluyen este pedazo de código:


if (isset($_SERVER['HTTP_CLIENT_IP'])
|| isset($_SERVER['HTTP_X_FORWARDED_FOR'])
|| !in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1'))
) {
header('HTTP/1.0 403 Forbidden');
exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}

Que en principio, parece que nos protege. Pero según creo, de esto por ahora sólo son conjeturas, si nuestro servidor está detrás de un proxy, permite saltarse la restricción debido a que una de las condiciones (isset($_SERVER[‘HTTP_X_FORWARED_FOR’))  permite bypasearlo. Por lo que habría que editarlo.

Cómo recomendación final, es importante revisar todos estos puntos cuando tengamos el proyecto en producción para evitar dar demasiadas pistas a posibles atacantes y ahorrarno un disgusto en el futuro.

A estas alturas del partido, podemos encontrar por la red numerosos artículos y opiniones contándonos las bondades de utilizar control de versiones, especialmente Git. Así que he decidido aportar mi granito de arena dando mi opinión de porqué hay que utilizar este fabuloso sistema de control de versiones. Voy a resumirlo en 10 puntos, que creo que cubre  la mayoría de ventajas, por supuesto no son todas, pero en mi opinión creo que sí las más importantes.

  1. Nos proporciona organización: esto es común a cualquier sistema de control de versiones, eso de tener 30 carpetas para diferenciar las versiones sólo nos suele traer dolores de cabeza, pérdida de tiempo y problemas a la hora de entregar un trabajo o ponerlo en producción.
  2. Podemos probar nuestro código de forma más ordenada sin necesidad de crear copias de los ficheros o el proyecto. Codeamos, probamos, que funciona, bien, que no funciona, hacemos un revert y no ha pasado nada.
  3. Nuestro código estará más limpio, ya que con Git no es necesario ir comentando código “por si luego lo uso”. Esto, aparte de ser una mala práctica, luego nos costará más mantener el código, mientras con git siempre podremos ver las versiones antiguas de nuestros archivos y rescatar código eliminado.
  4. Más sencillo controlar los cambios, proyectos y ver el historia. Si instalamos un visor web en nuestro servidor de repositorios, cómo GitLab, o utilizamos GitHub, podremos ver todos nuestros proyectos y navegar de forma sencilla por todas las versiones, ramas, etc.
  5. Las puestas en producción son más sencillas y rápidas, sobre todo hablando de entornos web. Hay gente que todavía utiliza el FTP cómo medio de subir los proyectos, y muchas veces sin comprimir, tardando bastante en subir un proyecto. Aparte de que si has cambiados varios ficheros y se te olvida subir alguno, puedes ocasionar errores en el funcionamiento de la aplicación. Con Git, basta con hacer un pull del proyecto para que suba los cambios casi de forma instantánea y sin dolores de cabeza.
  6. Sirve cómo sistema de copia de seguridad, siempre que lo tengamos en un servidor. Git trabaja de forma no destructiva, así que salvo que utilicemos uno o dos comandos especiales. Nuestra información siempre estará ahí. También donde tengamos un repositorio (servidor y diferentes máquinas), tendremos la historia completa del repositorio. Hay quien piensa que guardandolo en Dropbox o similares tenemos una copia de seguridad. Pero cómo accidentalmente borremos el proyecto de la carpeta, se borarrá entodos los equipos sincronizados. Esto me ha pasado y no fué agradable.
  7. Nos permite fiscalizar mejor nuestro trabajo. Hay veces que necesitamos un historial de los cambios de una aplicación para facturarlos o por otras necesidades. Esto, normalmente conlleva un tiempo buscando correos y papeles con las especificaciones o a veces ni eso ya que las peticiones se hicieron telefónicamente. Si usamos Git podremos ver de un vistazo todos los cambios y cuando se hicieron. Si a esto le añadimos una buena metodología en los mensajes de los commits, aparte del cuándo, podremos saber el qué se cambió.
  8. Compartir nuestro código, Git es ideal para hacer trabajo colaborativo, permitiendo desarrollos en paralelos y si utilizamos GitHub, podemos publicar nuestro código para que la comunidad lo aproveche y nos ayude a mejorarlo.
  9. Trabaja desde cualquier sitio, teniendo un servidor de Git (propio o GitHub) es tremendamente sencillo poder descargarte una versión de tu proyecto en cualquier sitio y trabajar fuera de tu ámbito normal. Esto viene genial para arreglar errores críticos que te pillen fuera de la oficina o por si pierdes o rompes tu equipo.
  10. Estaréis mejor visto laboralmente, actualmente en la gran mayoría de las ofertas de trabajo de programador, están pidiendo que se sepa utilizar un sistema de control de versiones, especialmente Git. Así que dedicándole un par de mañanas, podréis añadir a vuestro curriculum una nueva habilidad que os facilitará encontrar un empleo.

Espero haberos convencido, a aquellos que aún no lo utilicen, para probar este sistema y ver cómo vuestra calidad de vida de programadores.

Una de esas cosas que pasan de vez en cuando, al hacer una migración de un Plesk a otro nos pasó una cosa un poco rara. Normalmente tenemos en nuestro servidor  el webmail configurado para entrar con webmail.midominio.com.  Pero después de hacer la migración, un domino dejó de funcionar de esta forma. Así que en vez de acceder al webmail, nos mostraba la página por defecto de Plesk. Ni siquiera la página que corresponde al dominio.

Un error un poco raro, porque no esque haya dejado de funcionar Horde, ya que con el resto de los dominios que hay en el servidor configurados funcionaba perfectamente, sólo fallaba en uno.  No podía ser nada de DNS, ya que la redirección la hacía bien, así que tenía que ser algo de configuración de Plesk o de Apache. Tras buscar un buen rato una solución por la red, encontré este enlace http://benohead.com/horde-webmail-showing-the-default-plesk-page/ que me dio la solución al problema.

El apache que monta Plesk,  mantiene una configuración de Virtualhost para cada uno de los dominios que apunta hacia el Horde. Para ello, carga todos los ficheros de configuración de /etc/apache2/plesk.conf.d/webmails/horde . Si echamos un ojo al directorio, todos los ficheros siguen el mismo patrón, midominio.es_webmail.conf, y el dominio que estba dando fallo no tenía su fichero de configuración correspondiente. De forma que copiando uno de los archivos, poniéndolo el nombre y luego editando su interior, se soluciona el problema.


#ATTENTION!

#

#DO NOT MODIFY THIS FILE BECAUSE IT WAS GENERATED AUTOMATICALLY,

#SO ALL YOUR CHANGES WILL BE LOST THE NEXT TIME THE FILE IS GENERATED.

ServerAlias "webmail.midomino.com"

Simplemente cambiando el ServerAlias y reiniciando Apache, se soluciona

Llevo unos días cacharreando para montar una pequeña aplicación en Android. Así que tras un par de pruebas con el emulador, llega el momento de utilizar un dispositivo real, así que he cogido un Samsung Galaxy S (GT-I9000) que liberé hace algún tiempo y que tenía la ROM CreedROM_v11 puesta.

El caso esque al conectar  y lanzar la aplicación, no podía ver nada en el LogCat, sólo un error:

Unable to open log device '/dev/log/main': No such file or directory

Así que tras unas cuantas horas buscando por internet y probando cosas, conseguí dar con la solución. Para variar, es algo bastante simple, resulta que el loggin viene desactivado con esta ROM, así que para activarlo, hay que ir a la aplicación SemaphoreManager y activar el módulo Loggin, luego le damos un reinicio al teléfono y ya podremos ver los logs en LogCat y así depurar nuestra aplicación.  Espero que este pequeño tip sea de ayuda para alguién.

Este es el primero de una serie de tutoriales que pretendo publicar acerca de ir creando aplicaciones utilizando JSF 2.1.Intentaré centrarme en cómo se hacen ciertas tareas e ir creando material nuevo que o bien sea difícil de encontrar en nuestro idioma o no se haya publicado nada al respecto en ningún otro idioma. Por ello, pondré enlaces de recomendada lectura que vean que pueden aclarar conceptos, ya que es una tontería volver a publicar algo que esté bien explicado en otro lado.

Cómo primer objetivo, será entender el ciclo de vida y el proceso de creación de una aplicación sencilla en JSF, pero antes de nada, os recomiendo este enlace de adictos al trabajo  en el que se explican todos los conceptos de JSF sin entrar en mucho detalle.

Vamos a comenzar por crear un proyecto, para esta serie de tutoriales usaremos Netbeans 7.2 que ya viene incluido con soporte para JSF 2.1, un contenedor Tomcat 7.0.22 y soporte para Java EE6. Así que creamos un proyecto del tipo web application

Después hacemos las configuraciones del proyecto y pulsando Siguiente, hasta llegar a la elección de que frameworks queremos utilizar, entonces seleccionamos Java Server Faces

Ahora que tenemos el proyecto creado, vamos a crear un pequeño formulario para crear las estadísticas de un personaje de D&D. Necesitaremos  un backend bean, su diseño en facelet (XHTML) y una clase POJO para representar al personaje. Al final del articulo, encontrareis el proyecto que tiene la siguiente estructura:

Podréis observar las impresiones en consola que se hacen en los diferentes métodos, para que veamos y comprendamos mejor el ciclo de vida JSF aplicado al funcionamiento de una aplicación.

Así que vamos a echarle un ojo a la siguiente imagen del ciclo de vida:

ciclo de vida

Cómo podemos ver, tenemos diferentes fases, que en el enlace de adictos al trabajo se explica muy bien:

  1. Restaurar los conponentes de la vista (restore view). En esta etapa el controlador construye en memoria la estructura de componentes de la página.
  2. Aplicar los valores de la petición.. (apply request values). En esta etapa se recuperan los valores de la request y se asignan a los beans de la página.
  3. Procesamiento de las validaciones (process validations). Se verifican los parámetros de entrada según un conjunto de reglas definidas en un fichero de configuración.
  4. Actualizar los valores del modelo (update model values). Los valores leídos y validados son cargados en los beans.
  5. Invocacion a la aplicación (invoke application). Se ejecutan las acciones y eventos solicitados para la página. Si es necesario se realiza la navegación.
  6. Generación de la página (render response). En esta fase se genera la página que será enviada al usuario con todos sus elementos y valores actualizados.

Entonces, cómo afecta esto a nuestro proyecto?  Al  llamar por primera vez a la página, sólo se ejecutan las dos primeras fases, debido a que no hay información de la petición para relllenar el modelo.  Ahora el usuario rellena los datos y pueden ocurrir dos cosas, que haya algún error de validación, en cuyo caso no pasará del paso de validación y no se rellenará el modelo (nunca se ejecuta el setter) ni se ejecutará ninguna acción (no se ejecuta el método save() ). O bien que todo esté correcto, entonces ejecutará el siguiente paso de actualizar los valores del modelo y si no hay ningún error en este paso, se pasarían a ejecutar las invocaciones de los eventos, en este caso, se ejecutaría el método save().

También se puede ver, que el getter en el backend bean, se llama una vez por cada propiedad de la clase POJO, ya que a través de este getter obtenemos la clase POJO, por lo que si lo estuviéramos obteniendo con una consulta a una base de datos o algún otro método costoso, habrá que guardarlo en una variable del bean.

Por supuesto, esto se puede complicar más, porque habrá que tener en cuenta que ocurre cuando hay listeners  de por medio. Pero eso lo dejamos para otra entrada.

El proyecto entero, podeis descargarlo desde aquí.

Después de mucho sin actualizar, ya iba tocando.

Llevo algo más de un mes dandole duro a Symfony 2 otra vez. Esta vez con la versión 2.1, y estoy descubriendo un nuevo mundo utilizando composer para gestionar las dependencias.

Todo aquél que haya comenzado a utilizarlo, sabrá que el repositorio oficial de composer es https://packagist.org/, y aunque tiene un buscador muy bueno, no proporciona suficiente información acerca de los bundles que puedes encontrar. Aparte, de que no es un repositorio exclusivo de bundles de Symfony 2, aunque es lo que más hay.

Así que buscando esta mañana un Bundle para retocar imágenes, he dado con la página http://knpbundles.com/ , que contiene una gran cantidad de bundles (2003 actualmente). Nos da bastante información acerca de cada uno, así como el nombre y enlace para pacakgist (e incluirlo directamente en el composer.json) y la dirección en github. Desde luego , es lo suficientemente interesante cómo para dedicarle unos minutos de nuestro tiempo.

Desde hace unos meses que comencé a enredar con Icefaces 3, me topé con un problema al utilizar uno de los componentes más potentes para formularios. Se trata del componente  ace:dateTimeEntry,  para tener una bonita presentación a la hora de introducir fechas y horas en los formularios. El componente, dispone de dos formatos de presentación, el primero establece el calendario en bruto en la página y el segundo, y más útil, nos muestra un campo de texto que al recibir el foco, muestra un popup con el calendario para introducir la fecha. Un ejemplo de uso de esta esta segunda forma de renderización es la siguiente:

<ace:dateTimeEntry id="cal"
value="#{bean.persona.fechaNacimiento}"
timeZone="Canada/Mountain"
pattern="dd/MM/yyyy"
navigator="true"
yearRange="1940:1980"
renderAsPopup="true"/>

Con el atributo renderAsPopup , conseguimos que se renderice como un popup. Para el resto de opciones, aunque se explican por sí solas, podeis ver cómo funcionan en el showcase de icefaces. Una vez presentado el componente, vamos a ver el problema que me surgía y hasta la semana pasada no he conseguido dar con el origen. Cuando renderizaba el componente de esta forma,  el popup se mostraba, pero al realizar una navegación y volver al formulario, el popup con el calendario dejaba de mostrarse.  Después de mucho darle vueltas al porqué y preguntar en el foro de icesoft(sin mucho éxito), conseguí dar con el problema. Lo primero que hay que tener en cuenta, esque en Icefaces trabaja completamente con Ajax, con lo cual, cuando realizamos una actualización de sección, solo refresca la partede la página que ha cambiado. Para ello, el servidor envia como respuesta un XML con los cambios que ha habido. Entonces, en algunas páginas, esta respuesta, hacía cambiar el body entero, con una respuesta parecida a esta:

<div><partial-response></div>
<div><changes></div>
<update id="javax.faces.ViewBody"><body title=""><div id="header">...

En el momento que aparece <update id=”javax.faces.ViewBody”>, se nos fastidia el popup de dateTimeEntry, debería de aparecer un id de los que hayamos puesto nosotros. Tras revisar y revisar el código, el fallo está en algo bastante tonto, pero no trivial. Resulta que en las plantillas, para organizar las secciones de cada página, lo tenía dividido utilizando divs y algún que otro table, sin asignarle un id.  Y JSF, para detectar los cambios que hay en el DOM cuando cambiamos de navegación, utiliza los id para localizar que parte tiene que sustituir, así que asignandole un id, debería bastar, pero aún así, se dan comportamientos extraños. Por lo que lo mejor, es utilizar las etiquetas propias de JSF para organizar el código, que luego se sustituira en el cliente por un div.

De forma que para arreglar este error y evitar otros posibles funcionamientos erráticos, habría que sustituir (si tenemos algo parecido) esto:


<div id="content">

<ui:insert name="content"></ui:insert>

</div>

&nbsp;

&nbsp;

Por esto otro:


<h:panelGroup layout="block" id="content">

<ui:insert name="content"></ui:insert>

</h:panelGroup>

Y siempre, siempre, siempre, asignarle un id a los panelGroup, para que JSF encuentre correctamente donde tiene que sustituir al hacer cambios en el DOM.

Antes de nada, Feliz año a mis escasos lectores. Últimamente ando enfangado de nuevo con Java y por supuesto, con JasperReport para sacar informes. Con la aplicación que estoy desarrollando actualmente, estoy utilizando Icefaces 3 para JSF, que da muchas facilidades para crear aplicaciones rápidamente y atractivas, tanto visual como funcionalmente. Una de las cualidades de esta versión del framework, esque todo va por AJAX. Esto, al llegar al momento de presentar al usuario los informes creados con JasperReport, supone un problema. Ya que normalmente, nos inmiscuimos en el ciclo de vida de JSF para capturar la respuesta e imprimir nuestro informe, y esto no le sienta muy bien al framework.  Así que tras unas cuantas peleas y cabezazos contra el teclado, he conseguido llegar a una solución. Dicha solución consiste en sacar el informe en otra ventana, fuera del flujo de Icefaces. Y para presentar el informe, utilizo directamente un Servlet para generar la respuesta. Paso a explicar paso a paso.

Lo primero, tenemos en nuestro archivo .xhtml lo siguiente:

<h:commandButton id="pushButtonId12"  actionListener="#{informes.pdfEdificios}"  />

Utilizamos actionListener, para que no haga ningún refresco del contenido. Ahora, el código del método encargado de manejar dicho evento es el siguiente:


public String pdfEdificios(ActionEvent event) throws IOException{
try {
Connection con = edificiosDao.getConnection();
HashMap parameters = new HashMap();
String reportsDirectory = "c:/Users/Usuario/Documents/NetBeansProjects/Proyecto/build/web/";
String jasperName = "report1.jasper";
JasperPrint jasperPrint = UtilReports.generateReport(con, reportsDirectory, jasperName, parameters);
getSessionMap().put("report",jasperPrint);
JavascriptContext.addJavascriptCall(FacesContext.getCurrentInstance(), "window.open('Report', 'myWindow');");
} catch (NamingException ex) {
Logger.getLogger(Informes.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(Informes.class.getName()).log(Level.SEVERE, null, ex);
} catch (JRException ex) {
Logger.getLogger(Informes.class.getName()).log(Level.SEVERE, null, ex);
} catch (FileNotFoundException ex) {
Logger.getLogger(Informes.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}

En este método, simplemente generamos el informe mediante UtilReports.generateReport(con, reportsDirectory, jasperName, parameters), una vez hecho, guardamosel objeto JasperPrint a la sesión, para poder recuperarlo después en el Servlet.
Hasta este punto, ya tenemos el informe creado y guardado en la sesión, ahora necesitamos abrir el Servlet automáticamente para llevar el informe al usuario. Para ello, Icefaces nos proporciona JavascriptContext, desde el cual podemos añadir código javascript enviado desde el servidor.
Así que mediante JavascriptContext.addJavascriptCall(FacesContext.getCurrentInstance(), “window.open(‘Report’, ‘myWindow’);”); enviamos el código para que se abra una ventana nueva que lleva al servlet Report. Que habremos creado previamente con el siguiente código para manejar la respuesta:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
JasperPrint report =(JasperPrint) request.getSession().getAttribute("report");
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=" + "report" + ".pdf;");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
JRExporter exporter = new JRPdfExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, report);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, response.getOutputStream());
exporter.exportReport();
} catch (JRException ex) {
Logger.getLogger(Report.class.getName()).log(Level.SEVERE, null, ex);
}finally{
request.getSession().removeAttribute("report");
}

}

Aquí, recuperamos de la sesión el objeto JasperPrint de nuestro informes y preparamos las cabeceras de la respuesta para indicar el tipo, y utilizamos un exporter para exportar el informe en el formato deseado (normalmente pdf). Por último, es importante poner en el bloque finally, la liberación del objeto de la sesión, para no sobrecargar la memoria del servidor.
Esta es la única forma que he encontrado, de momento, para poder mostrar los informes sin entrar en conflicto con Icefaces. Si alguién tiene una solución mejor, que no dude en comentarlo.

Actualmente, a la hora de desarrollar aplicaciones, se utilizan multitud de frameworks que nos abstraen de la base de datos que se utilizan. A pesar de las ventajas que esto proporciona, tiene un pequeño “pero”. Perdemos el control sobre las consultas, y en algún momento del desarrollo acabaremos teniendo algún problema que podriamos solucionar rápidamente sabiendo la consulta exacta que se ejecuta.

Para evitar este tipo de cosas, Mysql dispone de un estupendo log de consultas, que podemos activar  y ver la consulta exacta que hace nuestro framework a la base de datos.

Para activar y ver dicho log es bastante sencillo:

mysql> set global general_log='on';
mysql> set global log_output='table';
mysql> select * from mysql.general_log\G

El resultado será algo parecido a esto:

*************************** 47. row ***************************
event_time: 2012-08-29 11:43:46
user_host: root[root] @ localhost [127.0.0.1]
thread_id: 85
server_id: 1
command_type: Query
argument: SHOW FULL COLUMNS FROM `activites` FROM `gas` LIKE 'journee'
*************************** 48. row ***************************
event_time: 2012-08-29 11:43:46
user_host: root[root] @ localhost [127.0.0.1]
thread_id: 85
server_id: 1
command_type: Query
argument: INSERT INTO gas.activites (id, matricule, secteur, secteur2, CIN,
journee) VALUES (0, 30, 4, 4, '12345678X', null)

Donde vemos las consultas que se hacen directamente en la base de datos y detectar posibles errores que nos den una idea de por donde encaminar una posible solución.

Una vez que acabemos, es recomendable desactivar los logs, por tema de eficiencia y para no llenar de basura la tabla, que en un futuro nos haga más dificil volver a buscar fallos.

mysql> set global general_log='off';

En caso de querer vaciar la tabla de log, tan sencillo como:

truncate table mysql.general_log;

Y para acabar, este truquito, lo ví en el libro Mysql Troubleshooting de O’Really , que tiene bastantes cosas interesantes respecto a mysql.