Integración Continua en Aplicaciones Web con Oracle ADF – Parte 3.1


Por Alexis Lopez Oracle ACE
Publicado en Septiembre 2017

En la primera parte de esta serie describimos brevemente el marco de trabajo Oracle ADF y su versión gratuita, tanto para desarrollar como para desplegar, ADF Essentials. También hablamos de la práctica de Integración Continua y su importancia en el desarrollo de aplicaciones usando dicho marco de trabajo.

En la segunda parte presentamos las dos primeras herramientas de nuestro ambiente de integración continua: Oracle JDeveloper como herramienta oficial de desarrollo y Git como sistema de control de versiones (VCS).

En la primera parte de esta tercera entrega, hablaremos de una herramienta muy importante que nos permitirá gestionar el ciclo de vida de la construcción del software así como del repositorio en donde almacenaremos los archivos/librerías generados (artefactos) para que puedan ser accedidos/usados por todo el equipo.

 

Acerca de Apache Maven

Apache Maven es una herramienta de código abierto utilizada en la gestión y construcción de software. Su objetivo es el de simplificar los procesos de construcción, generación de reportes y documentación del proyecto. Para poder operar, se basa en un concepto denominado Modelo de Objetos del Proyecto (POM por sus siglas en inglés), el cual es un documento XML que contiene lo necesario para describir el proyecto a construir, sus dependencias con otras librerías/módulos, versiones a usar, el orden de construcción, etc. Aunque es posible realizar configuraciones sobre el POM para ajustar a Maven al modelo de cada proyecto, se enfatiza en que son éstos, los proyectos, los que se deben adherir al modelo estándar definido por Maven y a esto se le conoce como “Convención sobre configuración”.

Para Maven, el proceso de construcción y distribución de artefactos (archivos/librerías generados como resultado de la construcción del software) está claramente definido en fases que son ejecutadas por plugins de maven. Las fases principales (existen fases adicionales) del ciclo de construcción del software definidas por Maven son, en su orden:

  • Validar (Validate): Verifica que el proyecto y el POM sean correctos.
  • Compilar (Compile): Realiza la compilación del código fuente.
  • Probar (Test): Ejecuta pruebas unitarias automatizadas (que se hayan desarrollado en el proyecto) sobre el código compilado.
  • Empaquetar (Package): Empaquetar el código compilado en el formato establecido para el proyecto, ejemplo: jar, war, ear…
  • Verificar (Verify): Verifica el resultado de pruebas de integración, si existe alguna.
  • Instalar (Install): Instalar el empaquetado en el repositorio local (hablaremos de esto más adelante), para poder usarlo como dependencia de otros proyectos.
  • Desplegar (Deploy): Despliega el empaquetado en el repositorio remoto (hablaremos de esto más adelante), para ser compartido con otros miembros del equipo y usado como dependencia de otros proyectos.

Cuando ejecutamos alguna de estas fases, se ejecutan todas las anteriores automática y secuencialmente. Es decir, si ejecutamos Empaquetar (Package), se ejecutarán primero: Validar, Compilar y Probar. Existen otras fases en el ciclo de construcción que no hemos especificado aquí, pero que están ampliamente documentadas en el sitio oficial de Maven.

Respecto a los reportes y documentación, Maven intenta resolver problemas frecuentes como la falta de documentación y la documentación desactualizada. Para ello, existen plugins que permiten automatizar la generación de documentación acerca del proyecto y crear/actualizar su sitio Web. Parte de esta información proviene del POM, por ejemplo: dependencias, tipo de licencia, equipo del proyecto, etc. Otra información es generada a partir del código fuente, como por ejemplo: estadísticas del repositorio de código fuente, análisis estático de código fuente, javaDocs, cobertura de las pruebas unitarias, resultado de pruebas unitarias, etc. Mayor información respecto a la configuración de estos reportes puede ser encontrada en el sitio oficial de maven.

Otra de las funcionalidades que nos ofrece Maven es la gestión de dependencias. Generalmente, los proyectos Java usan varias librerías (internas y externas), dichas librerías en ocasiones dependen de otras (dependencias transitivas) y en ocasiones esto lleva a la confusión y genera dudas en cuanto a cuáles descargar, de dónde descargarlas o si se está utilizando la versión correcta. Para solventar estas dudas, Maven define una estructura para localizar los artefactos (coordenadas) y gracias a ello, podrá descargarlos y adicionarlos al proyecto de forma automática con solo declararlos como dependencias en el POM del proyecto.

¿En qué consiste esta estructura? Lo primero que se define es el grupo que desarrolla el artefacto (groupId), luego su nombre (artifactId), versión (version) y por último el empaquetado (packaging). Veamos algunos ejemplos de librerías de código abierto que seguramente has usado en tus proyectos:

01
 

Existe una versión con un significado especial para los artefactos llamada SNAPSHOT. Cuando un artefacto tiene en su versión la palabra -SNAPSHOT, por ejemplo 1.0-SNAPSHOT, significa que ese artefacto se encuentra en desarrollo y que no es la versión 1.0 final. Esto es importante, ya que podemos configurar a Maven para que constantemente actualice nuestras dependencias marcadas como SNAPSHOT y así contemos siempre con las últimas construcciones de las dependencias en desarrollo. Eso sí, las dependencias SNAPSHOT solo deberían usarse durante desarrollo, una vez tengamos una versión final de la aplicación, no deberíamos tener dependencias de este tipo.

 

Repositorios Maven

Una vez hemos construido el software, es decir, hemos generado los archivos JARs, WARs, plugins u otros artefactos del proyecto, requerimos de un lugar en donde poder almacenarlos para que puedan ser accedidos por Maven y por el resto de los miembros del equipo de forma fácil.

¿Por qué no almacenar los artefactos en el repositorio de código fuente? Este es un tema controversial que tiene algunos votos a favor y otros en contra. Como sucede en la mayoría de situaciones, depende del proyecto, su tamaño, frecuencia de actualización, cantidad de dependencias, etc. A continuación algunos puntos en contra respecto a esta práctica:

  1. El repositorio de código fuente es para código fuente.
  2. El tamaño en disco usado por el repositorio de código fuente se hará grande rápidamente.
  3. La clonación del repositorio se hará más lenta.
  4. No se tendrá claridad acerca de la versión del artefacto.
  5. Cada vez que alguien del equipo requiera una dependencia, deberá clonar el repositorio para poder acceder a su artefacto.

En cambio, los repositorios Maven proveen un estándar para almacenar y servir este tipo de archivos y se dividen en dos (2) tipos, ambos usan la misma estructura definida por Maven:

    Local: Carpeta ubicada en la máquina del desarrollador, creada automáticamente por Maven y en la que se almacenan todas las dependencias de los proyectos. Cuando ejecutamos la construcción del software, Maven descargará las dependencias en esta carpeta, evitando que por cada construcción debamos descargar dependencias desde máquinas remotas.

    Por defecto, la carpeta creada es: {USER_HOME/.m2} donde USER_HOME es la carpeta del usuario en el sistema operativo. Si se desea, podemos cambiarla modificando el siguiente archivo: {M2_HOME}\conf\setting.xml, donde M2_HOME es la carpeta de instalación de Maven.

  • Remoto: Repositorio que no se encuentra en la máquina local del desarrollador. Puede ser privado, en donde podemos encontrar artefactos internos requeridos por el proyecto, o públicos como es el caso del repositorio central de Maven.

    El repositorio central de Maven es configurado por defecto, para los demás repositorios remotos existen dos formas de hacerlo: La primera consiste en modificar el POM del proyecto y la segunda en modificar el archivo {USER_HOME/.m2/settings.xml} donde USER_HOME es la carpeta del usuario en el sistema operativo. Más información acerca de estas configuraciones puede ser encontrada en este enlace de la documentación oficial de Maven.


A continuación los pasos ejecutados por Maven durante la búsqueda de dependencias que no sean SNAPSHOTS:

  1. Busca en repositorio local, si encuentra el artefacto, lo retorna, en caso contrario se mueve al paso 2.
  2. Busca en repositorio central, si encuentra el artefacto, lo copia al repositorio local y lo retorna, en caso contrario verifica si hay repositorios remotos configurados, si los hay se mueve al paso 3, si no los hay retorna error.
  3. Busca en repositorios remotos, si encuentra el artefacto, lo copia al repositorio local y lo retorna, en caso contrario retorna error.

Cuando tenemos dependencias marcadas como SNAPSHOTS, Maven sabe que estas dependencias no son estables y son susceptibles a cambios, por lo que buscará una nueva versión de la dependencia en los repositorios remotos, incluso si existe una versión de esta dependencia en el repositorio local.

Esto lo realiza una vez por día, pero es posible (y recomendado) configurarlo para que se realice siempre que el artefacto sea requerido o en intervalos de tiempo, simplemente debemos configurar un valor para la etiqueta updatePolicy en la configuración de repositorios.

Repositorio Interno y Administrador de repositorios Maven

En ambientes corporativos es común encontrar restricciones a la hora de acceder a Internet para descargar archivos, por tal motivo existen los llamados “repositorios internos”, los cuales se instalan en la misma red y para Maven son otro repositorio remoto desde donde los desarrolladores podrán descargar/publicar artefactos. Su uso se considera una muy buena práctica ya que nos provee un lugar central donde ubicar los artefactos generados y actúa como un proxy para los demás repositorios. Con esto mejoramos la estabilidad del sistema al no depender completamente de repositorios externos y reducimos tiempos de construcción porque todas las dependencias las podemos encontrar en la misma red.

También existen aplicaciones dedicadas a administrar este tipo de repositorios de una manera visual y declarativa, gestionar artefactos, usuarios, configurar la seguridad, incrementar la colaboración entre desarrolladores y muchas otras opciones. Entre dichas aplicaciones se encuentran:

  • JFrog Artifactorty → Soporta una gran variedad de tecnologías y al momento de escribir este artículo cuenta con versión para instalación así como versión en la nube. También ofrece una versión de código abierto llamada Artifactory.
  • Nexus Pro → Soporta las tecnologías más comunes y al momento de escribir este artículo sólo cuenta con versión para instalación. También ofrece una versión de código abierto llamada Nexus OSS.
  • Apache Archiva → Herramienta de código abierto para administrar repositorios Maven. Solo cuenta con versión para instalación.
  • Oracle Developer Cloud Service (DevCS) → Servicio en la nube de Oracle que va más allá de repositorios Maven, es una plataforma DevOps en la nube. Al momento de escribir este artículo, su uso está restringido, pero es gratuito para quienes cuentan con alguno de los demás servicios en la nube de Oracle: Java Cloud Service, Mobile Cloud Service y otros (visita la página oficial para mayor información).


Oracle JDeveloper y Maven

El IDE cuenta con una instalación de Maven dentro de sus carpetas, por lo que no es necesario instalaciones adicionales. Al momento de escribir este artículo, la versión incluida es la 3.2.5 y puede encontrarse en la siguiente ruta, donde {ORACLE_HOME} es la carpeta Oracle_Home de instalación de JDeveloper:

{ORACLE_HOME}/oracle_common/modules/org.apache.maven_3.2.5


Para acceder a las opciones de configuración de Maven dentro de JDeveloper, debemos acceder al menú Herramientas→Preferencias y en la ventana emergente, seleccionar la opción Maven:

02
 

La primera configuración que podemos notar es que estamos usando la versión que trae por defecto el IDE y la posibilidad de usar alguna otra versión externa instalada en nuestras máquinas. Sin embargo, esto puede llevar a incompatibilidades por cambios entre versiones de Maven y por ello recomendamos trabajar ya sea con la instalación que trae JDeveloper o alguna otra instalación en nuestras máquinas pero de la misma versión (3.2.5).

Otra configuración interesante son las fases de maven que podemos usar durante la construcción de nuestros proyectos. Algunas se encuentran preestablecidas pero podemos modificarlas o incluso adicionar otras:

03
 

Al adicionar fases podemos enviar parámetros e incluso agrupar varias de éstas bajo un solo nombre. Pensemos en esto como si estuviéramos creando accesos directos para, posteriormente, ejecutarlos durante la construcción de nuestros proyectos. En el siguiente ejemplo estamos creando un acceso directo denominado “clean compile” el cual ejecutará las fases clean y luego compile:

04
 

La siguiente opción nos permitirá definir el repositorio local (por defecto ubicado en {USER_HOME/.m2}) y también podremos almacenar definiciones de repositorios remotos que luego podremos copiar a nuestros proyectos:

05
 

Recomendamos indexar los repositorios manualmente puesto que es una tarea que consume tiempo y recursos y puede afectar el rendimiento de JDeveloper.

Por último, podemos definir donde se encuentra el archivo settings.xml con todas las configuraciones y otras opciones que serán pasadas al ejecutable de Maven:

06
 

El significado de cada una de estas opciones está por fuera del alcance del artículo, pero recomendamos al lector que se familiarice con ellas para saber cuando usarlas.

 

Obtener artefactos para desarrollar aplicaciones con Oracle ADF

Las aplicaciones desarrolladas con Oracle ADF usan muchos artefactos de Oracle y por ende, requerimos que nuestros repositorios Maven (local/remoto) cuenten con dichos artefactos para poder satisfacer las dependencias de nuestros proyectos.

Existen dos formas de obtener dichos artefactos:

  1. Instalación manual

    En este caso, requerimos de una instalación de Oracle JDeveloper, pues en sus carpetas se encuentra un plugin llamado oracle-maven-sync que se encarga de realizar el proceso, pero antes de poder usarlo, debemos instalarlo en el repositorio Maven local. El plugin se encuentra en:

    {ORACLE_HOME}/oracle_common/plugins/maven/com/oracle/maven/oracle-maven-sync/{JDEV_VERSION}

    Donde {ORACLE_HOME} es la carpeta Oracle_Home de instalación de JDeveloper y {JDEV_VERSION} es su versión, por ejemplo 12.2.1. Una vez navegamos a la ruta anterior, debemos ejecutar el siguiente comando para instalar el plugin en el repositorio local:

    mvn install:install-file
    -DpomFile=oracle-maven-sync-{JDEV_VERSION}.pom
    -Dfile=oracle-maven-sync-{JDEV_VERSION}.jar

    Donde {JDEV_VERSION} es la versión de JDeveloper, por ejemplo 12.2.1. Una vez instalado, podemos ejecutar el siguiente comando para instalar todos los artefactos de Oracle en el repositorio que indiquemos, este proceso puede tomar 30+ minutos:

    mvn com.oracle.maven:oracle-maven-sync:push -DoracleHome={ORACLE_HOME} -DserverId={SERVER}

    Donde {ORACLE_HOME} es la carpeta Oracle_Home de instalación de JDeveloper y {SERVER} es el identificador del repositorio en el que deseamos instalar los artefactos. El repositorio debe estar presente en alguno de los archivos de configuración especificados por Maven.

    Mayor información acerca de este proceso puede ser encontrada en la guía oficial del plugin Oracle-Maven-Sync (inglés).

     

  2. Configurar acceso al repositorio remoto Maven de Oracle

    Si no deseas instalar todas las librerías de Oracle en tu repositorio sino solo las necesarias para tus proyectos, puedes configurar el repositorio remoto Maven de Oracle para que sea accedido ya sea directamente desde nuestras máquinas o a través del repositorio interno. Al momento de escribir este artículo, podemos acceder a artefactos de las versiones 12.1.2, 12.1.3, y 12.2.1. Lo primero que debemos hacer es leer y aceptar la licencia de acceso al repositorio, lo cual lo podemos hacer a través del siguiente enlace con nuestras credenciales de Oracle:

     https://www.oracle.com/webapps/maven/register/license.html

     

    Para poder descargar los artefactos necesitamos una configuración adicional dependiendo desde donde queremos acceder al repositorio:

    • Si contamos con un repositorio interno (es una buena práctica contar con uno) debemos configurar su administrador (Jfrog, Nexus, Archiva, Oracle DevCS…) para que también acceda al repositorio remoto Maven de Oracle. Dicha configuración es diferente para cada uno de los administradores y se encuentra por fuera del alcance de este artículo, sin embargo, todos cuentan con interfaces gráficas que permiten una fácil configuración.

      Algunos ejemplos de cómo configurar repositorios remotos: Jfrog Artifactory, Apache Archiva. Si estamos usando Oracle DevCS, lo único que debemos configurar son las credenciales de Oracle para poder acceder al repositorio, todo lo demás ya se encuentra configurado.

    • En caso de no contar con un repositorio interno, debemos configurar el repositorio remoto tal como lo hemos discutido en la sección de “Repositorios Maven”, ya sea a nivel del proyecto (en su archivo POM) o a nivel de configuración de usuario (en el archivo {USER_HOME/.m2/settings.xml}). A continuación un ejemplo de configuración de este repositorio a nivel de usuario, para que funcione debemos cambiar los valores para username y password:

      <?xml version="1.0" encoding="UTF-8"?>
      <settings xmlns="http://maven.apache.org/settings/1.0.0" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 
      http://maven.apache.org/xsd/settings-1.0.0.xsd"><servers>     
          <server>
            <id>maven.oracle.com</id>
            <username>USER</username>
            <password>PASSWORD</password>
            <configuration>
              <basicAuthScope>
                <host>ANY</host>
                <port/>
                <realm>OAM 11g</realm>
              </basicAuthScope>
              <httpConfiguration>
                <all>
                  <params>
                    <property>
                      <name>http.protocol.allow-circular-redirects</name>
                      <value>%b,true</value>
                    </property>
                  </params>
                </all>
              </httpConfiguration>
            </configuration>
          </server>
        </servers> 
        <profiles>
          <profile>
              <id>oracle</id>
              <repositories>
                  <repository>
                      <id>maven.oracle.com</id>
                      <releases>
                          <enabled>true</enabled>
                      </releases>
                      <snapshots>
                          <enabled>false</enabled>
                      </snapshots>
                      <url>https://maven.oracle.com</url>
                      <layout>default</layout>
                  </repository>       
              </repositories>
              <pluginRepositories>
                  <pluginRepository>
                      <id>maven.oracle.com</id>
                      <url>https://maven.oracle.com</url>
                  </pluginRepository>
              </pluginRepositories>      
          </profile>
        </profiles>
        <activeProfiles>
          <activeProfile>oracle</activeProfile>
        </activeProfiles>
      </settings>				
      					


      La documentación oficial de configuración del repositorio remoto Maven de Oracle se encuentra en este enlace.



Conclusión

En la primera parte de esta tercera entrega hablamos acerca de Apache Maven como herramienta para la gestión y construcción del software. Aprendimos a configurar el acceso al repositorio Maven de Oracle para poder obtener los artefactos necesarios para la creación de aplicaciones ADF y exploramos algunas de las pantallas de configuración que ofrece JDeveloper para Maven.

A continuación algunos puntos para recordar:

  • Maven es una herramienta que nos permite simplificar y estandarizar los procesos de construcción, generación de reportes y documentación del proyecto. Define su estructura y configuración en un punto central denominado POM, donde se definen las dependencias del proyecto, los módulos que lo componen, configuración de las fases de la construcción, etc.

    Establece un estándar de nombramiento de artefactos para su fácil localización en los repositorios. Bajo este estándar, un artefacto se compone por su grupo de desarrollo, nombre, versión y empaquetamiento.

  • Los repositorios de artefactos se dividen en dos:
    • Local → En la máquina del desarrollador, por defecto ubicado en: {USER_HOME/.m2} donde USER_HOME es la carpeta del usuario en el sistema operativo.
    • Remoto → Ubicado en máquinas remotas, pueden públicos, ej: central Maven, o privados, ej: repositorios internos.
  • Los repositorios internos son considerados una muy buena práctica ya que nos proveen un lugar central donde ubicar los artefactos generados y actúan como un proxy para los demás repositorios. Con esto mejoramos la estabilidad del sistema al no depender completamente de repositorios externos y reducimos tiempos de construcción porque todas las dependencias las podemos encontrar en la misma red. Además, existen herramientas, comerciales y de código abierto, que permiten una fácil administración de estos repositorios.
  • Es recomendado establecer el valor always a la propiedad updatePolicy en la configuración de repositorios, en especial cuando trabajamos dependencias marcadas como SNAPSHOTS, ya que Maven sabe que estas dependencias no son estables y son susceptibles a cambios, por lo que buscará una nueva versión de la dependencia en los repositorios remotos, incluso si existe una versión de esta dependencia en el repositorio local.
  • Todos los artefactos requeridos para desarrollar aplicaciones con Oracle ADF se encuentran en la carpeta de instalación de JDeveloper y desde allí pueden ser instalados en el repositorio local o remoto. También se encuentran en el repositorio Maven de Oracle, al cual se puede acceder previo registro de tu cuenta Oracle.

En la segunda parte de esta tercera entrega veremos cómo desarrollar aplicaciones ADF usando Maven. Mientras tanto, continuamos armando nuestro ambiente de integración continua para Oracle ADF, en este momento se ve de la siguiente forma:

07



Información Adicional

Los siguientes enlaces ofrecen mayor información respecto a este tema:

Desarrollo de aplicaciones OFM usando integración continua (en inglés)
http://docs.oracle.com/middleware/1221/core/MAVEN/toc.htm

Maven
https://maven.apache.org

Artifactory
https://www.jfrog.com/artifactory

Apache Archiva
https://archiva.apache.org

Repositorio Maven de Oracle
http://maven.oracle.com

Oracle Cloud Developer Service
https://cloud.oracle.com/developer_service


Alexis Lopez (@aa_lopez) es consultor independiente Java/ADF. Ha sido profesor universitario de cursos relacionados con tecnologías Java y conferencista en congresos reconocidos como: Oracle Open World, JavaOne, Campus Party y OTN Tour. Cuenta con un título de ingeniero de sistemas y las siguientes certificaciones y reconocimientos: Oracle Ace, Duke Choice Award Latinamerica, OCP Java 8, OCPJMAD, OCPWCD y especialista de implementación de Oracle ADF. Es líder del grupo de usuarios Java de Cali-Colombia (www.clojug.org) y blogger activo en www.acelopez.com