Maven parent pom vs modules pom

Parece haber varias formas de estructurar poms padres en una comstackción multiproyecto y me pregunto si alguien tuvo alguna idea sobre cuáles son las ventajas / desventajas en cada sentido.

El método más simple de tener un pom padre sería ponerlo en la raíz de un proyecto, es decir,

myproject/ myproject-core/ myproject-api/ myproject-app/ pom.xml 

donde pom.xml es tanto el proyecto principal como describe los módulos -core -api y -app

El siguiente método es separar el padre en su propio subdirectorio como en

 myproject/ mypoject-parent/ pom.xml myproject-core/ myproject-api/ myproject-app/ 

Donde el padre pom todavía contiene los módulos pero son relativos, por ejemplo ../myproject-core

Finalmente, existe la opción donde la definición del módulo y el padre están separados como en

 myproject/ mypoject-parent/ pom.xml myproject-core/ myproject-api/ myproject-app/ pom.xml 

Donde el padre pom contiene cualquier configuración “compartida” (gestión de dependencias, propiedades, etc.) y myproject / pom.xml contiene la lista de módulos.

La intención es ser escalable para una construcción a gran escala, por lo que debe ser escalable para una gran cantidad de proyectos y artefactos.

Algunas preguntas de bonificación:

  • ¿Dónde está el mejor lugar para definir las diversas configuraciones compartidas como control de origen, directorios de implementación, complementos comunes, etc. (estoy asumiendo el padre pero a menudo me han mordido y han terminado en cada proyecto en lugar de uno común).
  • ¿Cómo se relacionan el complemento maven, hudson y nexus con la forma en que configuras tus proyectos múltiples (posiblemente una gran pregunta, es más si alguien ha sido sorprendido por cómo se ha configurado una comstackción multiproyecto)?

Editar: Cada uno de los subproyectos tiene su propio pom.xml, lo dejé para mantenerlo corto.

    En mi opinión, para responder a esta pregunta, debe pensar en términos de ciclo de vida del proyecto y control de versiones. En otras palabras, ¿el pom padre tiene su propio ciclo de vida, es decir, puede liberarse por separado de los otros módulos o no?

    Si la respuesta es (y este es el caso de la mayoría de los proyectos que se han mencionado en la pregunta o en los comentarios), entonces el padre padre necesita su propio módulo de un VCS y desde el punto de vista de Maven y terminarás con algo como esto en el nivel de VCS:

     root |-- parent-pom | |-- branches | |-- tags | `-- trunk | `-- pom.xml `-- projectA |-- branches |-- tags `-- trunk |-- module1 | `-- pom.xml |-- moduleN | `-- pom.xml `-- pom.xml 

    Esto hace que el pago sea un poco doloroso y una forma común de lidiar con eso es usar svn:externals . Por ejemplo, agregue un directorio de trunks :

     root |-- parent-pom | |-- branches | |-- tags | `-- trunk | `-- pom.xml |-- projectA | |-- branches | |-- tags | `-- trunk | |-- module1 | | `-- pom.xml | |-- moduleN | | `-- pom.xml | `-- pom.xml `-- trunks 

    Con la siguiente definición externa:

     parent-pom http://host/svn/parent-pom/trunk projectA http://host/svn/projectA/trunk 

    Una comprobación de trunks daría como resultado la siguiente estructura local (patrón n. ° 2):

     root/ parent-pom/ pom.xml projectA/ 

    Opcionalmente, incluso puede agregar un pom.xml en el directorio de trunks :

     root |-- parent-pom | |-- branches | |-- tags | `-- trunk | `-- pom.xml |-- projectA | |-- branches | |-- tags | `-- trunk | |-- module1 | | `-- pom.xml | |-- moduleN | | `-- pom.xml | `-- pom.xml `-- trunks `-- pom.xml 

    Este pom.xml es una especie de pom “falso”: nunca se lanza, no contiene una versión real, ya que este archivo nunca se lanza, solo contiene una lista de módulos. Con este archivo, una salida daría como resultado esta estructura (patrón n. ° 3):

     root/ parent-pom/ pom.xml projectA/ pom.xml 

    Este “truco” permite lanzar una comstackción de reactores desde la raíz después de un proceso de pago y hacer que las cosas sean aún más útiles. De hecho, así es como me gusta configurar proyectos maven y un repository VCS para grandes comstackciones : simplemente funciona, se escala bien, ofrece toda la flexibilidad que puedas necesitar.

    Si la respuesta es no (volviendo a la pregunta inicial), entonces creo que puedes vivir con el patrón n. ° 1 (haz lo más simple que pueda funcionar).

    Ahora, sobre las preguntas de bonificación:

    • ¿Dónde está el mejor lugar para definir las diversas configuraciones compartidas como control de origen, directorios de implementación, complementos comunes, etc. (estoy asumiendo el padre pero a menudo me han mordido y han terminado en cada proyecto en lugar de uno común).

    Honestamente, no sé cómo no dar una respuesta general aquí (como “usar el nivel en el que crees que tiene sentido mutualizar las cosas”). Y de todos modos, los poms de niños siempre pueden anular las configuraciones heredadas.

    • ¿Cómo se relacionan el complemento maven, hudson y nexus con la forma en que configuras tus proyectos múltiples (posiblemente una gran pregunta, es más si alguien ha sido sorprendido por cómo se ha configurado una comstackción multiproyecto)?

    La configuración que uso funciona bien, nada especial que mencionar.

    En realidad, me pregunto cómo el maven-release-plugin trata con el patrón n. ° 1 (especialmente con la sección ya que no puede tener dependencias SNAPSHOT en el momento del lanzamiento). Esto suena como un problema de huevo o de gallina, pero no puedo recordar si funciona y era demasiado perezoso para probarlo.

    Según mi experiencia y las mejores prácticas de Maven, hay dos tipos de “poms de padres”

    • pom padre “empresa”: este pom contiene la información y configuración específica de su empresa que hereda cada pom y no necesita copiarse. Estas informaciones son:

      • repositorys
      • secciones de gestión de distribución
      • configuraciones de plugins comunes (como las versiones de origen y destino de maven-compiler-plugin)
      • organización, desarrolladores, etc.

      La preparación de este pom padre debe hacerse con precaución, porque todos los poms de la empresa heredarán de él, por lo que este pom debe ser maduro y estable (¡la publicación de una versión del pom padre no debería afectar la publicación de todos los proyectos de su empresa!)

    • el segundo tipo de padre pom es un padre multimodular. Prefiero tu primera solución: esta es una convención maven predeterminada para proyectos de múltiples módulos, muy a menudo representa la estructura de código VCS

    La intención es ser escalable para una construcción a gran escala, por lo que debe ser escalable para una gran cantidad de proyectos y artefactos.

    Los Mutliprojects tienen estructura de árboles, por lo que no estás arrojado a un nivel de pom padre. Trate de encontrar una estructura de proyecto adecuada para sus necesidades. Un ejemplo clásico es cómo distribuir proyectos mutimodulares.

     distibution/ documentation/ myproject/ myproject-core/ myproject-api/ myproject-app/ pom.xml pom.xml 

    Algunas preguntas de bonificación:

    • ¿Dónde está el mejor lugar para definir las diversas configuraciones compartidas como control de origen, directorios de implementación, complementos comunes, etc. (estoy asumiendo el padre pero a menudo me han mordido y han terminado en cada proyecto en lugar de uno común).

    Esta configuración debe ser sabiamente dividida en un pom padre “de la compañía” y un pom (es) padre del proyecto. Las cosas relacionadas con todo lo que usted proyecta van al padre “de la compañía” y esto relacionado con el proyecto actual va al proyecto uno.

    • ¿Cómo se relacionan el complemento maven, hudson y nexus con la forma en que configuras tus proyectos múltiples (posiblemente una gran pregunta, es más si alguien ha sido sorprendido por cómo se ha configurado una comstackción multiproyecto)?

    El pom padre de la compañía debe ser liberado primero. Para los multiproyectos, se aplican reglas estándar. El servidor de CI necesita saber todo para construir el proyecto correctamente.

    1. Un padre independiente es la mejor práctica para compartir la configuración y las opciones en los componentes desacoplados. Apache tiene un proyecto padre pom para compartir avisos legales y algunas opciones de empaque comunes.

    2. Si su proyecto de nivel superior tiene un trabajo real en él, como agregar un javadoc o empaquetar una versión, entonces tendrá conflictos entre la configuración necesaria para hacer ese trabajo y la configuración que desea compartir a través de los padres. Un proyecto solo para padres lo evita.

    3. Un patrón común (ignorando el # 1 por el momento) es hacer que los proyectos con código utilicen un proyecto principal como su padre y hacer que use el nivel superior como padre. Esto permite que los objetos principales sean compartidos por todos, pero evita el problema descrito en el n. ° 2.

    4. El complemento del sitio se confundirá mucho si la estructura principal no es la misma que la estructura del directorio. Si desea construir un sitio agregado, tendrá que hacer algunos ajustes para evitar esto.

    5. Apache CXF es un ejemplo del patrón en # 2.

    Hay una pequeña captura con el tercer enfoque. Como los POM agregados (myproject / pom.xml) generalmente no tienen ningún elemento primario, no comparten la configuración. Eso significa que todos esos POM agregados tendrán solo repositorys predeterminados.

    Eso no es un problema si solo usas complementos de Central, sin embargo, esto no funcionará si ejecutas el plugin usando el formato de complemento: objective de tu repository interno. Por ejemplo, puede tener foo-maven-plugin con el groupId de org.example proporciona el objective generate-foo . Si intenta ejecutarlo desde la raíz del proyecto usando un comando como mvn org.example:foo-maven-plugin:generate-foo , no se ejecutará en los módulos agregados (consulte la nota de compatibilidad ).

    Varias soluciones son posibles:

    1. Implementar el complemento en Maven Central (no siempre es posible).
    2. Especifique la sección del repository en todos sus POM agregados (se rompe el principio DRY ).
    3. Haga que este repository interno esté configurado en settings.xml (en la configuración local en ~ / .m2 / settings.xml o en la configuración global en /conf/settings.xml). Hará que el build falle sin esos settings.xml (podría estar bien para grandes proyectos internos que se supone que nunca se construirán fuera de la compañía).
    4. Use la configuración principal con repositorys en sus POM agregados (¿podría haber demasiados POM principales?).