Herencia de la versión del proyecto Maven: ¿tengo que especificar la versión principal?

189

Tengo dos proyectos: Proyecto principal: A, Subproyecto: B

A / pom.xml:

<groupId>com.dummy.bla</groupId>
<artifactId>parent</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>pom</packaging>

Y en B / pom.xml, tengo:

    <parent>
        <groupId>com.dummy.bla</groupId>
        <artifactId>parent</artifactId>
        <version>0.1-SNAPSHOT</version>     
    </parent>

    <groupId>com.dummy.bla.sub</groupId>
    <artifactId>kid</artifactId>

Quiero que B herede la versión del padre, por lo que el único lugar en mi caso que necesito poner 0.1-SNAPSHOTes A/pom.xml. Pero si elimino el <version>0.1-SNAPSHOT</version>de B/pom.xmldebajo de la sección principal, Maven se queja de la versión que falta para el padre.

¿Hay alguna forma de usarla ${project.version}o algo así para evitar tenerla 01.-SNAPSHOTen ambos poms?

Shengjie
fuente
44
Tendrás que esperar a Maven 3.1 para eso.
Percepción
1
El enlace de arriba se ha movido. El estado final era "Cerrado / No se solucionará
jocull

Respuestas:

86

EDITAR: desde Maven 3.5.0 hay una buena solución para esto usando ${revision}marcador de posición. Vea la respuesta de FrVaBe para más detalles. Para versiones anteriores de Maven, vea mi respuesta original a continuación.


No, no hay Siempre debe especificar la versión de los padres. Afortunadamente, se hereda como la versión del módulo lo que es deseable en la mayoría de los casos. Además, la declaración de versión de este padre es eliminada automáticamente por Maven Release Plugin, por lo que, de hecho, no es un problema que tenga la versión en 2 lugares, siempre y cuando use Maven Release Plugin para lanzar o simplemente versiones.

Tenga en cuenta que hay algunos casos en que este comportamiento es bastante bueno y le brinda más flexibilidad que pueda necesitar. A veces, desea utilizar algunas de las versiones anteriores de los padres para heredar, sin embargo, ese no es un caso convencional.

Michał Kalinowski
fuente
3
Ahora puedes usar el ${revision}marcador de posición para esto. Ver mi respuesta ;-)
Viernes
2
Esto ahora está desactualizado - verifique la respuesta de @ FrVaBe aquí: stackoverflow.com/a/51969067/514483
robado el
@FrVaBe ¿y si tenemos padres anidados con diferentes versiones? No podemos usar una propiedad $ {revision} allí, no es suficiente.
Halil
@halil La pregunta es sobre heredar una versión de un padre con el objetivo de tener la misma versión en dos artefactos. Si tiene padres diferentes con versiones diferentes (en una jerarquía de herencia), probablemente no hará que todas tengan la misma versión. Por lo tanto, no entiendo completamente el comentario.
Viernes
86

Maven no está diseñado para funcionar de esa manera, pero existe una solución alternativa para lograr este objetivo (quizás con efectos secundarios, tendrá que intentarlo). El truco consiste en decirle al proyecto hijo que busque su padre a través de su ruta relativa en lugar de sus coordenadas maven puras, y además de externalizar el número de versión en una propiedad:

Padre pom

<groupId>com.dummy.bla</groupId>
<artifactId>parent</artifactId>
<version>${global.version}</version>
<packaging>pom</packaging>

<properties>
   <!-- Unique entry point for version number management --> 
   <global.version>0.1-SNAPSHOT</global.version>
</properties>

Niño pom

<parent>
   <groupId>com.dummy.bla</groupId>
   <artifactId>parent</artifactId>
   <version>${global.version}</version>
   <relativePath>..</relativePath>    
</parent>

<groupId>com.dummy.bla.sub</groupId>
<artifactId>kid</artifactId>

Utilicé ese truco durante un tiempo para uno de mis proyectos, sin ningún problema específico, excepto el hecho de que Maven registra muchas advertencias al comienzo de la construcción, lo que no es muy elegante.

EDITAR

Parece que maven 3.0.4 ya no permite tal configuración.

Yanflea
fuente
2
Sí, me temo que Maven no está diseñado para funcionar de esa manera, mejor solo quédate con poner las versiones en el sub pom.xml. El complemento de lanzamiento de Maven realmente no se preocupa por las versiones allí de todos modos.
Shengjie
77
para 3.0.5 funciona bien. aunque deberías poner <properties> en la parte superior.
ses
77
Funciona en 3.2.3. La ubicación de <properties> no importa. Sin embargo, recibirá una advertencia:'version' contains an expression but should be a constant.
Kapex
44
Por favor, ten cuidado con esto. Esto no funciona cuando otro proyecto hace referencia a su proyecto. La propiedad no se resolverá y se tratará literalmente (es decir, $ {my.version}). Esto conducirá a un error al resolver dependencias.
spekdrum
2
También he estado usando esto durante bastante tiempo y funciona bien (actualmente con maven 3.3.9) para un solo proyecto de múltiples módulos. Sin embargo, tan pronto como su proyecto se convierta en una dependencia de otro proyecto, las cosas se vuelven realmente difíciles. Realmente sugiero adoptar la sugerencia propuesta por @pay a continuación.
ingenioso
81

La forma más fácil de actualizar las versiones IMO:

$ mvn versions:set -DgenerateBackupPoms=false

(hazlo en tu carpeta raíz / pom principal).

Sus POM se analizan y se le pregunta qué versión configurar.

pai
fuente
17
También puede agregar -DnewVersion = {versionToBeUpdated} para evitar ingresarlo de forma interactiva.
Mukesh
1
Creo que esta es la mejor respuesta, automatiza los cambios de versión sin interrumpir los subproyectos (a los que no podría hacer referencia sin el pom padre).
Tarek
¡Sip! Esta es la respuesta. 🙌
aaiezza
Si las versiones de pom hijo y padre son inicialmente diferentes, primero actualícelas para que coincidan; de lo mvn versions:update-child-modules contrario, se omitirá toda la versión de pom del módulo hijo.
Gautam Tadigoppula
75

Desde Maven 3.5.0 puede usar el ${revision}marcador de posición para eso. El uso se documenta aquí: Versiones amigables de Maven CI .

En resumen, el pom padre se ve así (citado de la documentación de Apache):

<project>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.apache</groupId>
    <artifactId>apache</artifactId>
    <version>18</version>
  </parent>
  <groupId>org.apache.maven.ci</groupId>
  <artifactId>ci-parent</artifactId>
  <name>First CI Friendly</name>
  <version>${revision}</version>
  ...
  <properties>
    <revision>1.0.0-SNAPSHOT</revision>
  </properties>
  <modules>
    <module>child1</module>
    ..
  </modules>
</project>

y el niño pom así

<project>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.apache.maven.ci</groupId>
    <artifactId>ci-parent</artifactId>
    <version>${revision}</version>
  </parent>
  <groupId>org.apache.maven.ci</groupId>
  <artifactId>ci-child</artifactId>
   ...
</project>

También tienes que usar el complemento Flatten Maven para generar documentos pom con el número de versión dedicado incluido para la implementación. El HowTo está documentado en la documentación vinculada.

También @khmarbaise escribió una buena publicación de blob sobre esta característica: Maven: ¿Archivos POM sin una versión?

FrVaBe
fuente
Configuré mi proyecto como lo describiste, pero sin el "complemento Flatten Maven" y parece funcionar como se esperaba, ¿es esto posible? También recibí un error con maven 3.2.1, pero maven 3.3.9+ parece funcionar bien.
Max
@Max Depende de lo que defina como "trabajar como se espera". Supongo que la compilación pasará, pero instalar / implementar en un repositorio probablemente no sea una buena idea porque no hay un número de versión en el pom hijo, sino solo un marcador de posición (ver documentación )
Viernes
Uso <version> $ {revision} </version> en pom padre con propiedad predeterminada (<properties> <version> 0.1-default </version> </properties>. Los poms secundarios también usan <version> $ {revision} < / version>. Uso "mvn clean install -Drevision = 0.1. $ {bamboo.buildNumber}". Cuando escaneo los registros de la implementación, todo está configurado en 0.1.820 y 0.1-default ni siquiera está en los registros (820 es el buildNumber). Cuando escaneo el jar resultante, veo "Implementation-Version: 0.1.820" en el manifiesto, y también "version = 0.1.820" en un archivo pom.properties. El archivo pom tiene <version> $ {} revisión </ version> Así que creo que está bien.?
Max
1
@Max Intente resolver un jar donde la versión esté ${revision} en el pom (en el repositorio maven) como dependencia en otro proyecto. No creo que esto funcione.
Viernes
Esto es útil excepto cuando hago un lanzamiento. Eso reemplaza ${revision}en la etiqueta de la versión con la nueva versión
Mike D
21

Como mencionó Yanflea, hay una manera de evitar esto.

En Maven 3.5.0 puede usar la siguiente forma de transferir la versión desde el proyecto principal:

Parent POM.xml

<project ...>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mydomain</groupId>
    <artifactId>myprojectparent</artifactId>
    <packaging>pom</packaging>
    <version>${myversion}</version>
    <name>MyProjectParent</name>

    <properties>
        <myversion>0.1-SNAPSHOT</myversion>
    </properties>

    <modules>
        <module>modulefolder</module>
    </modules>
    ...
</project>

Módulo POM.xml

<project ...>
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.mydomain</groupId>
        <artifactId>myprojectmodule</artifactId>
        <version>${myversion}</version> <!-- This still needs to be set, but you can use properties from parent -->
    </parent>

    <groupId>se.car_o_liner</groupId>
    <artifactId>vinno</artifactId>
    <packaging>war</packaging>
    <name>Vinno</name>
    <!-- Note that there's no version specified; it's inherited from parent -->
    ...
</project>

Usted es libre de cambiar myversiona lo que quiera que no sea una propiedad reservada.

eFox
fuente
3
Al hacer referencia a un módulo de otro proyecto, Maven no resuelve la propiedad. ¿Eso es normal?
LeoLozes
Creo que esa pregunta puede ser digna de su propia entrada y no estar en un comentario como este. Sin ver tu código, solo puedo adivinarlo.
eFox
@LeoLozes ¿Resolvió su problema (módulo de referencia de otro proyecto)?
Morteza Malvandi
@MortezaMalvandi sí! Mi respuesta está en la parte inferior :)
LeoLozes
2
Maven 3.6.0 da una advertencia para esta configuración: "Se recomienda encarecidamente solucionar estos problemas porque amenazan la estabilidad de su compilación". "Por esta razón, las futuras versiones de Maven podrían dejar de admitir la construcción de proyectos con formato incorrecto".
d2k2
18

También puedes usar:

$ mvn release:update-versions -DdevelopmentVersion={version}

para actualizar los números de versión en sus POM.

Jerry Jin
fuente
10

La respuesta de eFox funcionó para un solo proyecto, pero no cuando hacía referencia a un módulo de otro (los pom.xml todavía estaban almacenados en mi.m2 con la propiedad en lugar de la versión).

Sin embargo, funciona si lo combina con el flatten-maven-plugin , ya que genera los poms con la versión correcta, no la propiedad.

La única opción que cambié en la definición del complemento es outputDirectory, está vacía por defecto, pero prefiero tenerla target, que está configurada en mi .gitignoreconfiguración:

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>flatten-maven-plugin</artifactId>
   <version>1.0.1</version>
   <configuration>
      <updatePomFile>true</updatePomFile>
      <outputDirectory>target</outputDirectory>
   </configuration>
   <executions>
      <execution>
         <id>flatten</id>
         <phase>process-resources</phase>
         <goals>
            <goal>flatten</goal>
         </goals>
      </execution>
   </executions>
</plugin>

La configuración del complemento va en el pom.xml padre

LeoLozes
fuente
0
<parent>
    <groupId>com.dummy.bla</groupId>
    <artifactId>parent</artifactId>
    <version>0.1-SNAPSHOT</version>     
 </parent>

 <groupId>com.dummy.bla.sub</groupId>
 <artifactId>kid</artifactId>

Quiere decir que desea eliminar la versión del bloque principal del pom de B, creo que no puede hacerlo, el groupId, artifactId y la versión especificaron las coordenadas de pom del padre, lo que puede omitir es la versión del niño.

Yu Chai
fuente