jueves, 23 de agosto de 2018

Maven (2) Proyectos multi-módulo

0. Introducción


Se va a seguir las bonísima guias de: 
Los proyectos multimódulo también se llaman aggregator projects. Y el mecanismo que los maneja en Maven es Reactor que recoge todos los módulos disponibles para ser ejecutados y los ordena y hace un build de uno en uno.

Veamos los pros y contras:

Pros:
  1. Se pueden tener un módulo con todas nuestras utilidades básicas  como tratamiento de ficheros, mapeadores de xml, generadores de bitácoras (logs), utiliades de reflexión, etc. Y así tenerlas siempre al dia y sin versiones anticuadas que pueden dar problemas.
  2. Se pueden crear módulos que sean independientes con sus ficheros de recursos (propiedades, persitence.xml..) que puedan ser aplicaciones por su cuenta.
  3. Se pueden crear módulos que dependan de otros, aprovechano el trabajo de módulos anteriores sin repetir código
Contras: (PERO TIENEN SOLUCIÓN)
  1. Hay que saber que un módulo en JPA solo mapea (reconoce) las clases que se han definido en él y no reconoce las clases definidas en otros módulos. Es decir, supongamos que tenemos 2 módulos, (modulo1 y modulo2) y al módulo2 le hemos indicado en el pom.xml que tiene una dependencia al modulo1, entonces el modulo2, puede ver a la clase Personas y usarla... pero las EntityManger definidas en el módulo2 no pueden ver a la clase Personas. Por tanto tenemos que tener un "persistence.xml" en el módulo1 que se encargue del manejo JPA de la clase Personas. 
  2. Los ficheros de recursos definidos en un módulo (dentro de src/main/resources), no son accesibles desde otro módulo (ficheros de propiedades, de internacionalización i18n, persistence.xml,..)
Pero...:
Hay que crear etiquetas <class> para cada clase que se tenga que utilizar dentro del persistence.xml 
  1. Parece ser que si tenemos un módulo final que obtenga un fichero tipo "war" para ser desplegado y que dependa de otros módulos, SI que podemos meter todos los recursos (propiedades, propiedades de internacionalización i18n, y persistence xml) en su src/main/resources, siempre que hagamos los siguientes pasos:  En el módulo padre: 1-> run as Maven clean, 2->Maven update project,  En la vendana de servidores 3-> Clean, 4-> Clean Tomcat Work directory. Ahora tenemos dos opciones a) Ejecutar el módulo hijo que va generar el war con Run on Server o la otra opción b) En el proyecto padre Run as Maven Build con Goals: clean package y Profiles: production. Con esto úlimo se generaran todos los jars y también el war del proyecto hijo.

2. Paso 1: Crear el proyecto padre (parent project)

Opción 1: Por línea de comandos

mvn archetype:create -DgroupId=org.proyecto -DartifactId=my-parent-project


Y le indicamos al pom.xml

<packaging>pom</packaging>


Opción 2: Si actuamos mediante Eclipse

File-New-Other-Maven-Maven Project-Next


Y ahora damos los nombre de grupo y artefacto de antes




Y ya temos el proyecto creado.

Importante, conviene darle ya la versió 1.0.0

3. Paso 2: Crear los proyectos submódulo o hijos


Opción 1: por línea de comandos

cd my-parent-project

mvn archetipe:generate -DgroupId=org.proyecto.core    -Dartifact=mycore

mvn archetipe:generate -DgroupId=org.proyecto.service -Dartifact=myservice

mvn archetipe:generate -DgroupId=org.proyecto.webaspp -Dartifact=mywebapp



Opción 2:  por Eclipse:

File-New-Other-Maven-Maven Module-Next


donde hacemos referencia al módulo padre



Ahora repetimos los mismos pasos para crear los módulos myservice y mywebapp

Y podemos ver que se han creado con esta estructura


4. Paso 3: Manejo de dependencias


Podemos declarar una dependencia en el padre y que se propague a todos sus hijos

Veamos el pom.xml del padre, en este caso la dependencia "lombok" puede ser utilizada por los hijos, es decir no hace falta declararla en los hijos.

Observemos también como hace referencia a los módulos hijos en el apartado modules

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.proyecto</groupId>
  <artifactId>my-parent-project</artifactId>
  <version>1.0.0</version>
  <packaging>pom</packaging>
  <name>MyParentProject</name>
  <description>Proyecto padre</description>
  
  <modules>
  	<module>mycore</module>
  	<module>myservice</module>
<module>mywebapp</module>
</modules>
<properties> <failOnMissingWebXml>false</failOnMissingWebXml> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <lombok.version>1.18.10</lombok.version> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <scope>provided</scope> </dependency> </dependencies> </project>


Si se hubierta especificado la versión en el hijo, entonces no haría caso a la versión del padre.

Si queremos cambiar el empaquetado de un hijo (por ejemplo a war), se entra en el pom.xml de ese hijo y se indica

<packaging>war</packaging>

Y hacendo un mvn clean install o ejecutando el pom.xml delpadre con el boton derecho run as "Maven build ..." y metiendo en Goals  clean install, queda


Y al ejecutar nos falla porque busca el web.xml para poder hacer el packaging a war. En efecto veamos la traza


[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] 
[INFO] my-parent-project                                                  [pom]
[INFO] mycore                                                             [jar]
[INFO] myservice                                                          [jar]
[INFO] mywebapp                                                           [war]
[INFO] 
[INFO] -------------------< org.proyecto:my-parent-project >-------------------
[INFO] Building my-parent-project 0.0.1-SNAPSHOT                          [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ my-parent-project ---
[INFO] 
[INFO] --- maven-install-plugin:2.4:install (default-install) @ my-parent-project ---
[INFO] Installing /home/eduard/WorkSpace_Photon/my-parent-project/pom.xml to /home/eduard/.m2/repository/org/proyecto/my-parent-project/0.0.1-SNAPSHOT/my-parent-project-0.0.1-SNAPSHOT.pom
[INFO] 
[INFO] ------------------------< org.proyecto:mycore >-------------------------
[INFO] Building mycore 0.0.1-SNAPSHOT                                     [2/4]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ mycore ---
[INFO] Deleting /home/eduard/WorkSpace_Photon/my-parent-project/mycore/target
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mycore ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ mycore ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ mycore ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ mycore ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ mycore ---
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ mycore ---
[INFO] Building jar: /home/eduard/WorkSpace_Photon/my-parent-project/mycore/target/mycore-0.0.1-SNAPSHOT.jar
[INFO] 
[INFO] --- maven-install-plugin:2.4:install (default-install) @ mycore ---
[INFO] Installing /home/eduard/WorkSpace_Photon/my-parent-project/mycore/target/mycore-0.0.1-SNAPSHOT.jar to /home/eduard/.m2/repository/org/proyecto/mycore/0.0.1-SNAPSHOT/mycore-0.0.1-SNAPSHOT.jar
[INFO] Installing /home/eduard/WorkSpace_Photon/my-parent-project/mycore/pom.xml to /home/eduard/.m2/repository/org/proyecto/mycore/0.0.1-SNAPSHOT/mycore-0.0.1-SNAPSHOT.pom
[INFO] 
[INFO] -----------------------< org.proyecto:myservice >-----------------------
[INFO] Building myservice 0.0.1-SNAPSHOT                                  [3/4]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ myservice ---
[INFO] Deleting /home/eduard/WorkSpace_Photon/my-parent-project/myservice/target
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ myservice ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ myservice ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ myservice ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ myservice ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ myservice ---
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ myservice ---
[INFO] Building jar: /home/eduard/WorkSpace_Photon/my-parent-project/myservice/target/myservice-0.0.1-SNAPSHOT.jar
[INFO] 
[INFO] --- maven-install-plugin:2.4:install (default-install) @ myservice ---
[INFO] Installing /home/eduard/WorkSpace_Photon/my-parent-project/myservice/target/myservice-0.0.1-SNAPSHOT.jar to /home/eduard/.m2/repository/org/proyecto/myservice/0.0.1-SNAPSHOT/myservice-0.0.1-SNAPSHOT.jar
[INFO] Installing /home/eduard/WorkSpace_Photon/my-parent-project/myservice/pom.xml to /home/eduard/.m2/repository/org/proyecto/myservice/0.0.1-SNAPSHOT/myservice-0.0.1-SNAPSHOT.pom
[INFO] 
[INFO] -----------------------< org.proyecto:mywebapp >------------------------
[INFO] Building mywebapp 0.0.1-SNAPSHOT                                   [4/4]
[INFO] --------------------------------[ war ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ mywebapp ---
[INFO] Deleting /home/eduard/WorkSpace_Photon/my-parent-project/mywebapp/target
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mywebapp ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ mywebapp ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ mywebapp ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ mywebapp ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ mywebapp ---
[INFO] 
[INFO] --- maven-war-plugin:2.2:war (default-war) @ mywebapp ---
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.thoughtworks.xstream.core.util.Fields (file:/home/eduard/.m2/repository/com/thoughtworks/xstream/xstream/1.3.1/xstream-1.3.1.jar) to field java.util.Properties.defaults
WARNING: Please consider reporting this to the maintainers of com.thoughtworks.xstream.core.util.Fields
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
[INFO] Packaging webapp
[INFO] Assembling webapp [mywebapp] in [/home/eduard/WorkSpace_Photon/my-parent-project/mywebapp/target/mywebapp-0.0.1-SNAPSHOT]
[INFO] Processing war project
[INFO] Webapp assembled in [9 msecs]
[INFO] Building war: /home/eduard/WorkSpace_Photon/my-parent-project/mywebapp/target/mywebapp-0.0.1-SNAPSHOT.war
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] my-parent-project 0.0.1-SNAPSHOT ................... SUCCESS [  0.232 s]
[INFO] mycore ............................................. SUCCESS [  0.509 s]
[INFO] myservice .......................................... SUCCESS [  0.020 s]
[INFO] mywebapp 0.0.1-SNAPSHOT ............................ FAILURE [  0.216 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.098 s
[INFO] Finished at: 2018-08-23T14:31:05+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war) on project mywebapp: Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml if executing in update mode) -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
[ERROR] 
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR]   mvn <goals> -rf :mywebapp


5. Paso 4: Módulos que dependen de otros

Supongamos que el módulo "myservice" depende del módulo "mycore"

entonces tendrá que haber una entrada de mycore en myservice

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 
  <modelVersion>4.0.0</modelVersion>
  
  <parent>
    <groupId>org.proyecto</groupId>
    <artifactId>my-parent-project</artifactId>
    <version>1.0.0</version>
  </parent>
  
  <groupId>org.proyecto.service</groupId>
  <artifactId>myservice</artifactId>
  <name>MyService</name>
  <description>Servicio</description>
  <version>1.0.0</version>
  
  <properties>
    <!-- Java version-->
    <java.version>13</java.version>  <!-- abans 12, 10 -->
  </properties>
  
  <dependencies>
    <dependency>
      <groupId>org.proyecto.core</groupId>
      <artifactId>mycore</artifactId>
      <version>1.0.0</version>
    </dependency>
  </dependencies>
  
</project>



No hay comentarios :

Publicar un comentario