sábado, 30 de enero de 2021

Cuando aprender o repasar se hace casi imposible

 La semana pasada intenté repasar lo que había hecho de Java Server Faces y, al mismo tiempo, aprender las novedades de las últimas versiones. Es increíble cómo se complicó la cosa:

Entorno de desarrollo

 En el mundo de Java tenemos varios IDEs, pero los principales son Eclipse (y sus derivados), Netbeans e IntelliJ IDEA. Éste último no lo he tocado... todavía. El caso es que cuando trabajé con JSF lo hice con Netbeans. La forma que tiene de crear proyectos y de configurar dependencias y, sobre todo, sus versiones, hace que sea muy amigable trabajar con él, pero su uso suele ser a nivel académico. Eclipse es el IDE que más he visto en entorno empresarial, así que siempre es mejor trabajar con el que vas a usar día a día para ir conociendo todas sus "tripas" lo mejor posible.


Creando el proyecto

 Aquí es donde se va todo al traste. A la hora de trabajar con aplicaciones web puedes crear un proyecto que sólo ese IDE entenderá (por ejemplo, un Dynamic Web Project) o un proyecto Maven que puedas exportar a cualquier otro IDE (o que cualquier software pueda entender). A mí se me juntaron varios problemas al mismo tiempo:
-La versión de Java.
-La versión del IDE.
-Las versiones de las dependencias:
    -Dynamic Web Module.
    -JSF.
    -Java.
-El servidor de aplicaciones y su versión.
 Empecemos con los dos primeros: si quiero usar la última versión de Eclipse (2020-12) necesito utilizar, como mínimo, la versión 11 de Java (así que si estoy trabajando con la 1.8 en el equipo ya me han dado por saco). Intenté tener instaladas ambas, pero Eclipse sólo detectaba la 1.8, así que se negaba a arrancar.
 Estuve configurando el "path", pero no sirvió de nada. Revisé ficheros de configuración para ver si había alguna forma de indicar la ruta que debía buscar e ignorar el "path", pero tampoco.
Ante esto a uno se le presentan dos opciones: buscar una versión anterior del IDE que trabajara con Java 1.8 (versión 2020-06 de Eclipse) o trabajar con la versión 11. Intenté esta última opción, pero me encontré con varios problemas. Ahora mismo no los recuerdo todos, pero uno de ellos fue el servidor de aplicaciones. Suelo utilizar Tomcat para trabajar con Java, pero para JSF, EJB, etc. mejor utilizar un servidor de aplicaciones completo, así que opté por Glassfish (que es con el que había aprendido). Y aquí la lista de problemas:
-La última versión de Eclipse sólo acepta la versión 5 de Glassfish (5.1.0 es la última de esa generación) y no la 6.0 (que, por cierto, sólo trabaja con la versión 11 de Java en adelante).
-Si configuraba que fuera el servidor de aplicaciones quien proveyera las librerías Java EE, Glassfish 5.X no reconoe las novedades que incorpora Java Server Faces 2.3. Por ejemplo, en esta última versión todas las anotaciones relacionadas con los ManagedBean están "deprecated". Ahora se usa @Named en lugar de @ManagedBeand. Y así con otras. Eso hacía que no pararan de saltarme "warnings" en el código. Se puede usar la anotación @SupressWarning("deprecation") para que no moleste, pero si estoy aprendiendo la última versión de todo no me parece normal andar así. Como digo, Glassfish 5.X no contempla estas novedades, así que lo que estaba haciendo en el código no funcionaba y no sabía por qué demonios era. Costó descubrir que el "culpable" era el puñetero servidor de aplicaciones ¬¬.
 Siguiendo el consejo de un libro (el cual comento al final del artículo) decidí cambiar a un "fork" de Glassfish: Payara. El problema es que en el libro se usa una versión de Eclipse anterior y la cosa se complicó:
-En el libro, Payara se instala como Glassfish, pero en Eclipse no me salía forma de instalarlo. Así que tienes que ir a la categoría Oracle (en la lista de "instalar nuevo servidor de aplicaciones"), instalas "Glassfish Tools" y te saldrá la categoría "Glassfish". El problema es que en mi versión de Eclipse no salían las "Glassfish tools", así que tuve que descubrir que había que instalar "Oracle Cloud Tools" (o algo así), para conseguir ver dicha categoría y conseguir instalar un Glassfish (o Payara). Por suerte, escoger este último método hace que se instalen gran cantidad de "cosillas" en Eclipse que facilitan mucho la vida del programador.
 Me gustaría comentar, también, que se pueden encontrar unas "Glassfish Tools" en Eclipse Marketplace, pero me dieron problemas. Lo que sí hay son unas "Payara Tools" que van muy bien para poder instalar el servidor de aplicaciones Payara de forma directa, sin tener que hacerlo como si fuera un Glassfish.
 Del mismo modo, en el libro que estaba siguiendo te explican que si instalas las "JBoss Tools" desde el "Marketplace" se abre un abanico inmenso de cosas por instalar (esto sólo me funcionó bien en la versión de Eclipse 2020-06). Para el proyecto que estaban mostrando en dicho libro. lo deshabilitaban todo y sólo marcaba/instalaba las utilerías de inyección de dependencias (que vienen de fábula, para que negarlo) y, luego, en la lista de servidores de aplicaciones disponibles instalaba las "JBoss, Wildfly tools..." que también incorporan muchas novedades a Eclipse y, de paso, la posibilidad de instalar el servidor de aplicaciones Widlfly  (versión 21) que va estupendo para todo.
 En resumen, al final me quedé con la versión Eclipse 2020-06 que permite trabajar Java 1.8 y he instalado la última versión de Payara Tools y el servidor de aplicación Payara, las JBoss Tools (que, como he comentado antes, en la última versión de Eclipse no aparece la pantalla de marcar/desmarcar que quiero instalar), las "JBoss, Wildfly tools..." desde la ventana de "Instalar nuevo servidor de aplicaciones", el servidor de aplicaciones Wildfly y la última versión de Apache Tomcat. Y, por ahora, todo funciona correctamente.


Creando el proyecto

 Una vez decides que vas a trabajar con Eclipse, la versión de Java 1.8, instalar X servidores de aplicaciones y configuras el entorno como lo necesitas, toca pasar a crear el proyecto. Y aquí es cuando se vuelve a liar, porque cada IDE es distinto y los "docentes" no suelen crear dichos proyectos pensando en que el estudiante va a necesitar crearlos en otros IDE o de otras formas. 
 Entonces, ¿qué opción se elige? Pues hay varias:
-Se puede crear un "Dynamic Web Project" y, luego, convertirlo a Maven Project. Está es la forma más rápida y cómoda, ya que te permite configurar el proyecto como Java Server Faces mientras lo creas.
-La forma más estandarizada por los profesionales suele ser crear un "Maven Project", pero aquí se complica cuando debes elegir un arquetipo. Lo mejor es no dejarte abrumar por ello, así que lo más sencillo es marcar la casilla "Create a simple project" y centrarte más en el tipo de "packagin" que vas a utilizar (Pom, JAR, WAR). Para una aplicación web usamos WAR y esto ya configura todas las carpetas y archivos mínimos que el proyecto necesita. 
 También se puede escoger el arquetipo "maven-archetype-webapp" (que va por la versión 1.4) que hará algo muy parecido, aunque con ciertos añadidos. 
 Por suerte, cualquier proyecto Maven te permite añadir lo que quieras a mano y siempre puedes configurar el proyecto vía "Project Facets" en Eclipse.
 Éstas son las diferencias más obvias (a primera vista) entre estas (ya que hay montones) dos formas de crear un proyecto con "Maven Project":


Arquetipo "Create a simple project"


-JAX-WS Web Services: es decir, el proyecto está configurado para trabajar con Web Services.
-Se crea la estructura de carpetas:
src/main/java
src/main/resources
src/test/java
src/test/resources
-El archivo pom.xml no incluye apenas nada.
-En "Project facets" encontramos "Dynamic web module 2.5", "Java 1.5" y "JavaScript 1.0".


Arquetipo "Maven archetype webapp"


-Se crean los archivos WEB-INF/web.xml e index.jsp en la carpeta src/main/webapp.
-El archivo pom.xml es bastante más completo.
-En "Project facets" encontramos "Dynamic web module 2.3", "Java 1.7" y "JavaScript 1.0".


Configurando "Project Facets"


 Y aquí es cuando te vuelves mico. Pongamos un ejemplo distinto a los anteriores: si creamos un Maven Project pelado, sin estructura de carpetas ni ninguna dependencia, podemos ir a configurar el proyecto a "Project Facets". Esto es lo que he conseguido aprender:
 Si "Dynamic Web Module" está marcada hay que desmarcarla, darle al botón "Apply". Luego, se elije versión y se vuelve a marcar la casilla. Importante: Según la versión que elijas tendrás que subir la de Java. Entonces, en la parte inferior de la pantalla aparece un link donde se lee "Further configuration available". Hay que hacer clic, porque si el fichero web.xml no viene creado de antemano es así cómo podemos crearlo de forma automática. Siempre se puede hacer a mano, claro, pero mucho mejor si ayuda el entorno.
 Esto mismo hay que repetirlo con Java Server Faces, ya que crea el fichero faces-config.xml y con JPA, que crea su fichero correspondiente: persistence.xml en src/main/java/META-INF.
 Si nos olvidamos de darle al link podemos marcar y desmarcar de nuevo (dándole al botón "Apply") o seleccionar otra tecnología con la que trabajar (como JSF o JPA) y verás que aparece una nueva pantalla (relacionada con esa tecnología) pero que permite ir hacia atrás o hacia adelante, con lo cual puedes configurar la que se te había pasado (aunque recomiendo hacer cada cosa por separado).
 Otra cosa importante es que muchas veces no aparecen carpetas como src/main/java. Esto se puede habilitar en propiedades del proyecto / Java Build Path / Order and Export y marcando alguna de las casillas vacías (por ejemplo, Maven Dependencies, etc.). Esto obligará a que aparezcan las que están marcadas con el cuadrito negro. Por mi parte, las marco todas. Y ya tendremos el proyecto con toda la estructura necesaria. A partir de aquí ponemos las dependencias en el pom.xml (vía interfaz gráfica o a mano) y configuramos un servidor de aplicaciones para el proyecto (entre muchas otras cosas).


Final


Éstas son algunas de las dificultades con las que me encontré sólo para poder crear un proyecto para Java 1.8, Dynamic Web Module 4.0, Java Server Faces 2.3 y JPA 2.2. Creo que me surgieron más problemas, pero estos son los que recuerdo. Es importante recalcar que esto no es un tutorial, sino un aviso de los problemas con los que te puedes llegar a encontrar. Así que, para que esto no te pase, te dejo aquí la documentación que te irá mejor para poder trabajar con estas tecnologías:
-Libro "The Definitive Guide to JSF in Java EE 8". Se puede encontrar un PDF en internet.
-Java: 1.8.
-IDE: Eclipse 2020-06
-Servidor de aplicaciones: Payara (instalando las Payara Tools) es el que utilizan en el libro, pero también puedes usar WildFly (el antiguo JBoss) 21.
-Dynamic Web Module: 4.0
-JSF: 2.3.
-JPA: 2.2.
-CDI (Contexts and Dependency Injection): 2.0. En el libro te piden instalarlo vía Marketplace con las JBoss Tools (recuerda que con Eclipse 2020-12 no me funcionó como esperaba). Al instalarlo te permite crear clases especiales como Beans, XHTML, etc. sin tener que hacer una estándar y cumplimentarla tú.
En Udemy y Youtube encontrarás varios tutoriales de JSF, pero vigila con los IDEs que utilizan y sus distintas versiones. Lo mismo que con las tecnologías especificadas anteriormente (JSF; JPA, etc). Al final te vuelves mico cuando empieza a fallar una cosa u otra respecto a lo que ves en el curso (y, por desgracia, no siempre es posible acceder a las versiones que esta gente usa en sus tutoriales).