domingo, 22 de marzo de 2009

javax.persistence.PersistenceException: No Persistence provider for EntityManager.... SOLUCIONADO

El otro día tuve que montar a un compañero un entorno para trabajar con un proyecto. El procedimiento, el de siempre: bajar glassfish, bajar eclipse (Ganymede) y hacer el (SVN) checkout oportuno del proyecto. A los pocos minutos ya estaba todo montado... pero me encontré con un problema incomprensible:




Este mismo proyecto (con el mismo código y librerías) estaba funcionando correctamente en dos máquinas, así que era incomprensible. ¡PersistenceManager informa de que no encuentra alguna de sus propias clases! Obviamente no tenía nada que ver con el código, así que, como uno es perro viejo, pensé que tenía que ser de otros factores diferenciadores. Igualé las versiones de Glasfish: nada. Actualizé el JDK: nada.... La única diferencia era que las otras máquinas donde funcionaba correctamente sin problemas (una de ellas, la mía) eran Linux (Kubuntu, para más señas) y ésta era un Haselfroch. Miré en un foro un post que hablaba algo sobre un directorio con acentos, pero no era el caso. Afortunadamente, uno tiene la suerte de trabajar junto a amables compañeros y buenos profesionales que me ayudaron a echar un vistazo, y comenzó eso que viene a llamarse brainstorming, donde cada uno empieza a decir en alto las cosas que observa o se le pasan por la cabeza. Es un metodo infalible: al poco rato ya teníamos una pista. Mirando en la consola de Glassfish aparecían caraceres multibyte en la ruta donde desplegaba la aplicación debido a que había espacios en dicha ruta.

En resumen: la aplicación se había desplegado usando la integración de Glassfish con eclipse (muy buena por cierto), ya que se comporta como si tuviesemos el tomcat embebido: rápida y cómoda. En una instalación por defecto, el eclipse pone el Workspace en el directorio de usuario, que en Haselfroch es C:\Documents and Settings\usuario\... y las aplicaciones se despliegan en dicho workspace. En definitiva, por algún bug extraño de la implementación en Toplink Essentials, el PersistenceManager no encuentra los persistence providers de marras si hay caracteres mutibyte en el path.

Solución: asegurate que tu aplicación (que usa EntityManager) se despliegue en un directorio sin espacios, acentos o caracteres no ASCII. Si estás usando Eclipse y usas Windoze, cambia el workspace de Eclipse a un directorio sin espacios... o mejor, usa Linux (nunca hay que perder la oportunidad de "evangelizar" ;-).

P.D.: Por cierto que Microsoft debería plantearse de una vez por todas dejar de poner por defecto los datos de usuario en una partición por defecto que se suele formatear una vez al año como mínimo y que además, todo el mundo desaconseja usar y así, tomar ejemplo de sus propios usuarios y crear un sencillo "home" (en lugar de "Documents and Settings") en otra partición... fórmula de eficacia demostrada desde hace decenas de años... pero en fin, sería pedir cosas "razonables", que no se yo....

martes, 17 de marzo de 2009

Facelets: el fin de la crisis diseño/desarrollo provocada por JSF

Típicamente se define Facelets como un sistema de plantillas para JSF al estilo de Tapestry para Struts, pero en realidad la definición se queda pobre y, desde mi punto de vista, no es representativa de sus características más importantes. En este artículo expondré por qué es tan importante y daré las suficientes razones como para que nadie que desarrolle JSF se resista a usarlo.

JSF: La crisis diseño/desarrollo

JSF tiene muchas ventajas para el desarrollo de aplicaciones web, especialmente para las aplicaciones ricas tipo RIA que tengan necesidades de presentación de datos de forma interactivas, ya que nos permite ver las aplicaciones como "formularios" y "componentes" al estilo de las aplicaciones de escritorio y nos oculta todo el engorro de bajo nivel web (POST, GET, trabajo con objetos del contenedor de Servlet directamente, etc,..). Sin embargo, el modelo de desarrollo de JSF requiere un cambio conceptual en los equipos de desarrollo que en algunas ocasiones es duro:
  • Los desarrolladores que están acostumbrados a una programación lineal tipo scripting (JSP/JSTL, PHP, ASP, etc...) se encuentran ahora con un modelo de componentes con su "ciclo de vida" específico: un elemento bajo otro no necesariamente se interpreta/ejecuta después de otro.
  • La forma de trabajar clásica era partir de un diseño realizado y "hacerlo dinámico" o al revés, el equipo de diseño/desarrollo toma la aplicación "fea" de desarrolladores y le aplica el diseño. Con JSF esta forma de trabajar es muy complicada y frustrante:
    • Para aplicar diseño a los componentes hay que conocer los componentes y el modelo de trabajo, así que los diseñadores/maquetadores se encuentran con su pequeño infierno teniendo que pegarse con "cosas de los desarrolladores" que desconocen.
    • Partir de un diseño y aplicar componentes es igual de frustrante y de poco exitoso. Y justo al igual que en el otro caso, la mayoría de los desarrolladores pierden mucho tiempo en intentar "pegarse" con CSS y "cosas de los maquetadores" que desconocen. Mantener la maquetación y composición que han realizado los diseñadores se convierte en un infierno.
  • Los controles de layout (panels, tabs, boxes, etc...) son un dolor de cabeza para los maquetadores/diseñadores que se ven obligados a aprender las técnicas de skinning de cada librería de componentes y se encuentran con que es imposible aplicar sus diseños correctamente
  • Con JSP/JSTL se puede utilizar la reutilización de presentación vía Custom Tag Files y/o includes... pero hacer componentes con JSF es es un verdadero engorro y los f:subviews son imprácticos en la mayoría de los casos.
En definitiva, el ahorro de tiempo en y las ventajas en robustez y legibilidad de la aplicación no acaban de compensar el mayor coste de desarrollo y la inconveniencia de dos equipos de trabajo que han empezado a trabajar incómodos y descoordinados. Así que el uso de JSF parece que se relega a aplicaciones donde el diseño tenga poco peso e importancia, o al menos en favor de la interactividad y la riqueza de la experiencia de usuario, es decir: intranets o aplicaciones de gestión/administración de sistemas.


Facelets al rescate

Desde luego, las aplicaciones donde JSF presta todas sus ventajas son aquellas en las que no es necesario un diseño previo. Para este tipo de aplicaciones el desarrollador puede usar las librerías de componentes existentes para crear interfaces muy usables, funcionales y con un aspecto realmente espectacular para un en entorno web, sin tareas de maquetación y/o diseño adicionales.

Sin embargo hay proyectos en los que se opta por una tecnología más tradicional, como JSTL, para que los desarrolladores, pero especialmente los diseñadores/maquetadores tengan total libertad en el aspecto final de la interfaz, sacrificando las ventajas de la programación con JSF y sus útiles componentes.

Sin embargo, Facelets puede ofrecernos esa libertad sin renunciar a trabajar con un modelo MVC como JSF:
  • Las páginas con facelets son XHTML, tal cual. Los diseñadores/maquetadores se sentirán tan cómodos como con una página JSTL/JSP, y las herramientas de diseño podrán interpretarlas como HTML que son.
  • Se puede poner texto, tags HTML y expresiones EL en cualquier parte de la página y Facelets las evaluará correctamente: se acabó tener que usar los engorrosos h:outputText o f:verbatim sólo para poner una propiedad de un bean o un tag HTML. Esto te permite, por ejemplo, que sean los diseñadores/maquetadores los que establezcan el layout de los componentes y su aspecto, y así evitar tener que usar componentes para alinear dos campos o centrar un texto.
  • Te permite trabajar "al estilo JSTL", es decir, como usando JSP con tags: lo que  ponemos "debajo de" se interpretará "después de". Esto es así porque aunque con Facelets se produce un árbol de componentes (no un servlet como con JSP), el árbol de componentes es coherente con el ciclo de vida de JSF.
En definitiva, Facelets te permite trabajar con JSF de una forma más natural, y la curva de aprendizaje para desarrolladores que no hayan trabajado con JSF es mucho más liviana. Con Facelets podemos volver a conciliar la crisis de los equipos de trabajo en los proyectos web, ya que la forma de trabajo vuelve a ser más amistosa con los diseñadores y el modelo de componentes "encaja" de nuevo con una visión orientada a documentos desde el punto de vista del diseño.

Aún hay más

Desde mi punto de vista y en el mundo de desarrollo en el que me muevo, las características comentadas son las más importantes de Facelets, y sólo por ello, ya merecería la pena usarlo. No obstante, Facelets es una tecnología de "Vista" específicamente diseñada para JSF, así que nos depara muchas gratas sorpresas funcionales extremadamente interesantes:
  • Plantillas. Facelets es un sistema de plantillas con JSF en mente, lo que nos permite acelerar el desarrollo enormemente con la misma facilidad y enfoque con el que se puede considerar a JSP un sistema de plantillas para servlets (el cuerpo de una JSP acaba siendo el método jspService()).
  • Desarrollo cero para componentes. Hacer un componente JSF (o "componentizar" un trozo de una página) es tan simple como extraerlo en un fichero aparte. Facelets es a los componentes JSF lo que fueron los Custom Tag Files a JSP 2.0. Una maravilla.
  • Informes de errores precisos. El tiempo que tarda un desarrollador JSF en interpretar los ininteligibles mensajes de error es indirectamente proporcional a sus "horas de vuelo". Los mensajes de error nunca indican en qué componente, y menos aún en qué línea se ha producido. Es un proceso de adivinación a base de leer las decenas de líneas del Stack trace. Con Facelets tenemos por fin errores precisos sobre la línea, tag y atributo donde se ha producido. Otra de ésas razones por las que merecería la pena usarlo, aunque fuese la única.

Conclusiones

Facelets se debe añadir por defecto a cualquier proyecto JSF, aunque no se vayan a hacer componentes ni plantillas. Usar HTML y tener errores informados son razones suficientes para incorporarlo siempre. De hecho se añadirá al estándar en JSF 2.0.

Más información:
https://facelets.dev.java.net/
http://wiki.java.net/bin/view/Projects/Facelets
http://www.ibm.com/developerworks/java/library/j-facelets/
https://facelets.dev.java.net/nonav/docs/dev/docbook.html

Banco de experiencias (I): JSF con Apache Myfaces Trinidad

Apache Myfaces Trinidad es uno de los frameworks JSF open source más completos y  sólidos actualmente. Son el resultado y la evolución de la donación de Oracle ADF Faces por parte de Oracle a la ASF. Es el más completo, estable y probado de los 3 de Apache, con una solidez demostrada con el paso de los años (es tan antiguo que usaba Ajax antes de lo llamaran Ajax, sino PPR -Partial Page Rendering-).

Por su envergadura y características, está en el grupo de "los grandes": frameworks multipropósito con enorme catálogo de componentes y características avanzadas (Ajax, templating, skinning, etc...). Otras compañeras de grupo de élite de frameworks/librería de componentes JSF son:

Como ventajas importantes de Trinidad destacaría:
  • Es compatible con otras librerías de componentes, como Tomahawk.
  • Se integra perfectamente con Facelets (de hecho, no sólo son un tándem perfecto, sino que no concibo JSF sin Facelets)
  • Tiene decenas de componentes y te permite hacer una aplicación "rica" de una forma cómoda. A destacar el tr:table. Sólo por ese componente merece la pena usarlo. Si tienes que presentar tablas de información interactivas, es la mejor forma.
  • Ha demostrado funcionar razonablemente bien en aplicaciones de producción y tiene un desarrollo y evolución constante.
Eso sí, Trinidad adolece de inconvenientes propios además de los comunes a este tipo de frameworks:
  • La documentación deja bastante que desear
  • Para que tenga un aspecto decente hay que prepararle un skin o, directamente usar los componentes de Oracle ADF Faces, que ya traen uno impecable.
En definitiva, a falta de probar en condiciones ICEfaces, es una estupenda alternativa en los siguientes casos:
  1. Aplicación extranet tipo RIA (o al menos necesidad de "rich controls") y pilotamos de CSS o tenemos alguien en el equipo que pilota. En cualquier caso procura evitar los controles de layout (panels, tablas, etc...)
  2. Aplicación intranet RIA. Si no tenemos a maquetadores web en el equipo y te gusta el skin por defecto de Oracle, puedes usar directamente la implementación de Oracle.

Hay una interesante tabla comparativa de las distintas liberías de componentes en http://www.jsfmatrix.net.

lunes, 16 de marzo de 2009

Banco de experiencias (introducción)

Con este título, "Banco de experiencias", iré realizando (eso intentaré al menos, aunque aún no sé con qué frecuencia) aportaciones de mis experiencias en situaciones reales (no en laboratorio) y/o de sistemas en producción, probados en el mundo real.

Uso "banco de experiencias" como paráfrasis contrapuesta a "banco de pruebas", ya que ésto último, las pruebas, son el pan de cada día y sufrimiento diario de todos los arquitectos y desarrolladores de software. Y es que, a pesar de la cantidad de horas de desarrollo y buenas prácticas que tengamos encima, siempre tenemos la sensación de estar frente a algo nuevo. Y en realidad no es una sensación. Es la realidad. No hay dos sistemas iguales: siempre tienes que integrar con algo nuevo, siempre te encuentras que, cuando vas a hacer la instalación en producción resulta que el cliente no te había contado algo o que, simplemente, ni se te pasó por la cabeza y aparece algún elemento "metiendo ruido" como sacado de una chistera de repente.

El problema de la ingeniería del software, y del desarrollo, es que no se trabaja con materiales precisos, ni tenemos formas de medir objetivamente parámetros y tolerancias de los sistemas que nos permitan asegurar un mínimo de calidad. Además, contruimos sistemas "sobre" y/o "cooperativos" (sic) con otros (sean hardware o software) de los que no podemos tener mínimas garantías (y así lo podemos encontrar de forma expresa en las licencias de software privativo), con lo que no podemos garantizar tampoco el que construimos nosotros (suponiendo que pudiésemos).

Así, la "alta disponibilidad" se consigue, no garantizando sistemas que no fallen, sino garantizando que, cuando fallen (que lo harán) habrá otro sistema para ocupar su lugar. Un concepto éste, el de la "redundancia", ampliamente usado por los distintos generales de infantería de todos los ejércitos durante la historia. Ojalá pudiésemos implementar "alta disponibilidad" en el cuerpo humano a base de redundar el corazón, el cerebro...

En el mundo JEE, por ejemplo, me he encontrado muchas veces que una aplicación construida por nosotros tiene una falla inexplicable. Tras muchas pruebas y averiguaciones nos encontramos con un bug del servidor de aplicaciones o de la JVM...Los indicadores de ese tipo de fallos, así como los de los nuestros propios, y las soluciones aportadas nos van generando un conocimiento empírico, procedimental, que sedimenta formando lo que algunos llaman "expertise" o sabiduría. Por eso, los fallos que suele tener un programador novato no suelen ser los mismos que un programador experimentado. Los desarrolladores experimentados, como decía unamuno, comienzan a dar en el clavo porque han dado ya muchas veces en la herradura. Y digo bien: "experimentado". No todos los desarrolladores experimentados son expertos.

Dijo Aldous Huxley, que "La experiencia no es lo que te sucede, sino lo que haces con lo que te sucede". Y es cierto que hay unos pocos experimentados que acaban convirtiendo el error en experiencia, y son capaces de mezclar la experiencia propia y la ajena con su propia intuición creativa: ésos son los expertos (algún día tendré que hablar largo y tendido sobre el tremendo componente creativo que tiene el desarrollo de software, a pesar de lo que muchos puedan pensar).

La ventaja del mundo del software frente a nuestra vida cotidiana es que en lo que respecta al primero sí podemos aprovecharnos y aprender de la experiencia ajena: no hace falta que suframos el mismo problema que otro durante 20h hasta encontrar la solución, podemos ahorrarnos 19,5h si el otro nos cuenta su experiencia y nosotros la recordamos en ese momento.

De hecho, los patrones de diseño (una de las herramientas imprescindibles de cualquier desarrollador) no son más que un catálogo de experiencias resumidas: los problemas y sus soluciones aplicadas y comprobadas.


Hasta ahora he sido un usuario "pasivo" de esto de la blogocosa.... Pero creo que me toca ahora agradecer la generosidad de otros uniéndome a ellos, participando, compartiendo y aportando "my two cents" al acceso del conocimiento común y de la experiencia colectiva a través de mis propias experiencias y así, asumir mis propias disfunciones metacognitivas (gracias, Sr. Galli, por el magnífico artículo).

"Sólo una cosa es más dolorosa que aprender de la experiencia, y es, no aprender de la experiencia" (Laurence Johnston Peter, 1919-1990, Profesor y escritor canadiense).

viernes, 6 de marzo de 2009

UIXCollection$Transient cannot be cast to [Ljava.lang.Object; SOLUCIONADO

Llevo dos días perdidos con ese error. Al final he conseguido resolver el enigma. El contexto es el siguiente:
  • Aplicación JSF usando MyFaces Trinidad (ocurre tanto con trinidad 1.2.10 como con 1.2.11)
  • Servidor Glassfish v2.1
  • Una página (jspx) con una tabla (tr:table) presentando datos. Desde esa página (la primera petición funciona) realizo lo siguiente:

    • pulso en cualquier command o link
    • pulsar botón atrás del navegador (volvemos a la página con la tabla)
    • pulso en cualquier otro command o link de la página ==> crash
El log del servidor es inservible a efectos de descubrir la razón del problema:




Buscando en google encontré esto que me dió la pista y probé a borrar el comentario que tenía inmediatamente después del <tr:table> y... ¡ bingo !.
Era eso. El error sigue estando en páginas jspx incluso en versiones muy posteriores a las comentadas, así que se ve que no está solucionado (aún).

En definitiva: no pongas comentarios dentro de un tr:table.
Espero que este post sirva para ahorrar tiempo a algún otro sufridor.
Related Posts Plugin for WordPress, Blogger...
cookieassistant.com