2010-01-02 14 views
256

Parece haber varias formas de estructurar poms padres en una compilación multiproyecto y me pregunto si alguien tenía alguna idea sobre cuáles son las ventajas/desventajas en cada sentido.Maven parent pom vs modules pom

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 el pom.xml es tanto el proyecto principal, así como describe la -API núcleo-e módulos -App

el siguiente método es separar a los padres en su propio subdirectorio como en

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

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

Por último, está la opción en la definición del módulo y el padre se separan como en

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

Cuando el pom principal contiene cualquier configuración "compartida" (DependencyManagement, propiedades etc.) y myproject/pom.xml contiene la lista de módulos.

La intención es ser escalable a 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 los distintos configuración compartida como en control de código fuente, los directorios de implementación, etc. plugins comunes (estoy asumiendo que el padre, pero a menudo he sido mordido por esto y terminaron en cada proyecto en lugar de uno común).
  • ¿Cómo se relacionan el complemento, hudson y nexus de maven-release con la forma de configurar sus proyectos múltiples (posiblemente una gran pregunta, es más si alguien ha sido atrapado cuando por la forma en que se ha configurado una construcción multiproyecto)?

Editar: Cada uno de los subproyectos tiene su propio pom.xml, lo he dejado fuera para mantenerlo corto.

+0

¿Los módulos tienen cada uno su propio pom también? Mi proyecto tiene un pom padre, pero los módulos también tienen un pom. (tal vez una cuarta forma de lo que describes) – harschware

+0

Ah, sí, voy a editar y actualizar. Cada uno de los submódulos tiene su propio pom también. –

+3

Al igual que una actualización, puedo ver una ventaja de la segunda opción es que es más fácil de administrar en Eclipse donde la raíz pom.xml en el primer y tercer ejemplo sería difícil de incluir si los submódulos son proyectos separados en Eclipse . –

Respuesta

153

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 pom padre tiene su propio módulo de un VCS y desde un punto de vista Maven y que va a terminar con algo como esto en el nivel VCS:

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

esto hace que la caja un poco doloroso y una forma común para hacer frente a esto es utilizar svn:externals. Por ejemplo, agregar un directorio trunks:

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

Con la definición siguientes factores externos:

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

una salida de trunks entonces dar lugar a la siguiente estructura local (patrón 2 #):

root/ 
    parent-pom/ 
    pom.xml 
    projectA/ 

Opcionalmente, incluso puede agregar un pom.xml en el directorio 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 es puesto en libertad, que no contiene una versión real, ya que este archivo no se libera, sólo contiene una lista de módulos. Con este archivo, un check out resultaría en esta estructura (patrón # 3):

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

Este "piratear" permite poner en marcha de un reactor de acumulación de la raíz después de una caja y hacer las cosas aún más práctico. En realidad, así es como me gusta configurar proyectos maven y un repositorio VCS para grandes compilaciones: simplemente funciona, se escala bien, ofrece toda la flexibilidad que pueda necesitar.

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

Ahora, sobre las preguntas de bonificación:

  • ¿Dónde está el mejor lugar para definir los distintos configuración compartida como en control de código fuente, los directorios de implementación, etc. plugins comunes (estoy asumiendo que el padre, pero A menudo me han mordido esto y han terminado en cada proyecto en lugar de uno común).

Sinceramente, no sé cómo no da una respuesta general aquí (como "utilizar el nivel en el que usted piensa que tiene sentido para mutualizar las cosas"). Y de todos modos, los poms de niños siempre pueden anular las configuraciones heredadas.

  • Cómo hacer el plugin de liberación Maven, Hudson y mucho nexo con la forma de configurar las múltiples proyectos (posiblemente una pregunta gigante, es más si alguien ha sido capturado cuando por la forma en un multi-proyecto construir ha sido configurado)?

La configuración que utilizo 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 <parent> 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.

+0

+1 Similar aquí. Buena idea con svn: externals! – mhaller

+0

Eso es muy bueno ya que puedo ver cómo se escala. El svn: externals responde mi preocupación acerca de que sea engorroso. –

+0

@jamie Me alegra que lo encuentre útil. –

21
  1. Un padre independiente es la mejor práctica para compartir la configuración y las opciones de 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 las configuraciones necesarias para hacer ese trabajo y las configuraciones que desea compartir a través del padre. Un proyecto solo para padres lo evita.

  3. Un patrón común (ignorando el n. ° 1 por el momento) es que los proyectos con código usen un progenitor principal como padre y lo usen como el principal. 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 primaria 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 el n. ° 2.

+2

He echado un vistazo a ibilio y muchos proyectos parecen preferir el pom padre "independiente". Hibernate, ActiveMQ, Jetty, XStream, etc. Lo que sugiere que es el mecanismo de facto. –

+2

Otra desventaja del padre independiente parece ser que el complemento de lanzamiento de maven parece querer que el padre se vincule a una versión antes de que se publique. Probablemente no sea un problema ya que el padre no debería cambiar demasiado. –

31

Desde mi experiencia y mejores prácticas Maven hay dos tipos de "poms padres"

  • "compañía" pom padres - esto pom contiene su empresa específica información y configuración que heredan todos los pom y no necesita ser copiado Estas informaciones son:

    • repositorios
    • secciones managment
    • distribución
    • configuraciones de plugins comunes (como las versiones de destino experto-compilador-plugin de origen y)
    • organización, desarrolladores, etc

    Preparación este pom padre debe hacerse con precaución, ya que 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 de pom padre no debería afectar para lanzar todos los proyectos de su empresa!)

  • segundo tipo de padre pom es un padre multimodular. Yo prefiero la primera solución - esto es una convención experto defecto para proyectos de varios módulos, muy a menudo representa la estructura del código VCS

La intención es ser escalable para una gran acumulación de escala por lo que debe ser escalable a un gran número de proyectos y artefactos.

Mutliprojects tienen estructura de árboles - por lo que no se arrown a un nivel de padre pom. Tratar de encontrar una estrutura proyecto adecuado para sus necesidades - una exmample clásico es cómo disrtibute proyectos mutimodule

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 los distintos compartida configuración como en control de fuente, directorios de implementación, complementos comunes, etc. (Estoy asumiendo que el padre pero a menudo me han mordido esto y han terminado en cada proyecto en lugar de uno común).

Esta configuración tiene que ser dividido sabiamente en una "compañía" pom de los padres y de los padres del proyecto POM (s). 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 hacer el plugin de liberación Maven, Hudson y mucho nexo con la forma de configurar las múltiples proyectos (posiblemente una pregunta gigante, es más si alguien ha sido capturado cuando por la forma en un multi-proyecto construir ha sido configurado)?

Empresa parent pom debe ser lanzado primero. Para los multiproyectos, se aplican reglas estándar. El servidor de CI necesita saber todo para construir el proyecto correctamente.

+0

Para que haya dos tipos de proyectos/poms principales. Uno sin declarar . Este es el que se usa para Herencia. Y un proyecto principal con la declaración . Este es uno de los que los submódulos no heredan, solo es para administrar la construcción del proyecto de retención. ¿Estoy en lo cierto? – lisak

8

Hay un pequeño inconveniente 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 repositorios predeterminados.

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

Varias soluciones son posibles:

  1. Implementar el plugin para Maven central (no siempre es posible).
  2. Especifique la sección del repositorio en todos sus POM agregados (se rompe el principio DRY).
  3. Tenga este repositorio interno configurado en settings.xml (ya sea 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 repositorios en sus POM agregados (¿podría haber demasiados POM principales?).
Cuestiones relacionadas