Herança da versão do projeto Maven - tenho que especificar a versão pai?

189

Eu tenho dois projetos: Projeto pai: A, Subprojeto: B

A / pom.xml:

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

E em B / pom.xml, tenho:

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

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

Quero que B herde a versão do pai, então o único lugar no meu caso que preciso colocar 0.1-SNAPSHOTé A/pom.xml. Mas se eu remover a <version>0.1-SNAPSHOT</version>partir B/pom.xmlsob a seção pai, perito reclama a versão que falta para o pai.

Existe uma maneira que eu possa simplesmente usar ${project.version}ou algo assim para evitar ter os 01.-SNAPSHOTdois peitos?

Shengjie
fonte
4
Você terá que esperar pelo Maven 3.1 por isso, receio.
Percepção
1
O link acima foi movido. O status final era "Closed / Won't Fix" issues.apache.org/jira/browse/MNG-624
jocull

Respostas:

86

EDIT: Desde o Maven 3.5.0, existe uma boa solução para isso usando ${revision}espaço reservado. Veja a resposta de FrVaBe para detalhes. Para versões anteriores do Maven, veja minha resposta original abaixo.


Não, não existe. Você sempre precisa especificar a versão dos pais. Felizmente, é herdada como versão do módulo o que é desejável na maioria dos casos. Além disso, a declaração da versão dos pais é enviada automaticamente pelo Maven Release Plugin, portanto, na verdade, não é um problema que você tenha a versão em dois locais, desde que você use o Maven Release Plugin para liberar ou apenas liberar versões.

Observe que existem alguns casos em que esse comportamento é realmente bom e oferece mais flexibilidade que você pode precisar. Às vezes, você deseja usar parte da versão do pai anterior para herdar, no entanto, esse não é um caso comum.

Michał Kalinowski
fonte
3
Agora você pode usar o ${revision}espaço reservado para isso. Veja a minha resposta ;-)
FrVaBe
2
Esta é agora fora da data - cheque @ resposta de FrVaBe aqui: stackoverflow.com/a/51969067/514483
robd
@FrVaBe e se tivermos aninhado pais com versões diferentes? Não podemos usar uma propriedade $ {revision} lá, não é suficiente.
halil
@halil A questão é herdar uma versão de um pai com o objetivo de ter a mesma versão em dois artefatos. Se você tiver pais diferentes com versões diferentes (em uma hierarquia de herança), provavelmente não fará da mesma versão todos eles. Portanto, não compreendo completamente o comentário.
FrVaBe
86

O Maven não foi projetado para funcionar dessa maneira, mas existe uma solução alternativa para atingir esse objetivo (talvez com efeitos colaterais, você precisará tentar). O truque é dizer ao projeto filho para encontrar seu pai através de seu caminho relativo, em vez de suas coordenadas puras, além de externalizar o número da versão em uma propriedade:

Pom pai

<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>

Pom criança

<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>

Eu usei esse truque por um tempo em um dos meus projetos, sem nenhum problema específico, exceto pelo fato de o maven registrar muitos avisos no início da construção, o que não é muito elegante.

EDITAR

Parece que o maven 3.0.4 não permite mais essa configuração.

Yanflea
fonte
2
sim, receio que o maven não seja projetado para funcionar dessa maneira, é melhor ficar colocando as versões no sub pom.xml. O plugin maven release realmente não se importa com as versões existentes.
Shengjie
7
para 3.0.5 funciona ok. você deve colocar <properties> no topo.
ses
7
Funciona em 3.2.3. A localização de <properties> não importa. Você receberá um aviso:'version' contains an expression but should be a constant.
kapex
4
Por favor, tenha cuidado com isso. Isso não funciona quando seu projeto está sendo referenciado por outro projeto. A propriedade não será resolvida e será tratada literalmente (por exemplo, $ {my.version}). Isso levará à falha ao resolver dependências.
Spekdrum
2
Também estou usando isso há um bom tempo e funciona muito bem (atualmente com o maven 3.3.9) para um único projeto multi-módulo. No entanto, assim que seu projeto se torna uma dependência de outro projeto, as coisas ficam realmente complicadas. Eu realmente sugiro adotar a sugestão proposta por @pay abaixo.
engenhoso
81

A maneira mais fácil de atualizar as versões IMO:

$ mvn versions:set -DgenerateBackupPoms=false

(faça isso na sua pasta pom raiz / pai).

Suas POMs são analisadas e você pergunta qual versão definir.

pai
fonte
17
Você também pode adicionar -DnewVersion = {versionToBeUpdated} para evitar inseri-lo interativamente.
Mukesh
1
Eu acho que essa é a melhor resposta, ela automatiza as alterações de versão sem quebrar os subprojetos (que você não seria capaz de referenciar sem o pom pai).
Tarek
Sim! Essa é a resposta. Aa
aaiezza 23/02/19
Se a versão filho e pai pom forem inicialmente diferentes, atualize-as primeiro para que correspondam; caso mvn versions:update-child-modules contrário , toda a versão pom do módulo filho será ignorada.
Gautam Tadigoppula 10/03
75

Desde o Maven 3.5.0, você pode usar o ${revision}espaço reservado para isso. O uso está documentado aqui: Versões amigáveis ​​do Maven CI .

Em suma, o pom pai se parece com isso (citado na documentação do 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>

e a criança pom assim

<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>

Você também precisa usar o Flatten Maven Plugin para gerar documentos pom com o número de versão dedicado incluído para implantação. O HowTo está documentado na documentação vinculada.

Também @khmarbaise escreveu um ótimo post sobre esse recurso: Maven: Arquivos POM sem uma versão nele ?

FrVaBe
fonte
Eu configurei meu projeto como você descreveu, mas sem o "Flatten Maven Plugin" e parece funcionar conforme o esperado, isso é possível? Também recebi um erro no maven 3.2.1, mas o maven 3.3.9+ parece funcionar bem.
Max
@ Max Depende do que você define como "trabalho conforme o esperado". Eu acho que a construção vai passar, mas instalar / deploy para um repositório provavelmente haverá boa idéia porque não há nenhum número de versão no pom criança mas apenas um espaço reservado (ver documentação )
FrVaBe
Eu uso <version> $ {revision} </version> no pai pom com propriedade padrão (<properties> <versão> 0.1-default </version> </properties>. Os filhos-filhos também usam <versão> $ {revision} < / version>. Uso "mvn clean install -Drevision = 0.1. $ {bamboo.buildNumber}". Quando examino os logs da implantação, tudo é definido como 0.1.820 e 0.1-default nem está nos logs (820 é o buildNumber). Quando varro o jar resultante, vejo "Implementation-Version: 0.1.820" no manifesto e também "version = 0.1.820" em um arquivo pom.properties. O próprio arquivo pom possui <versão> $ {revisão} </ version> Então, eu acho que é bom.?
Max
1
@ Max Tente resolver um jar onde a versão está ${revision} no pom (no repositório maven) como dependência em outro projeto. Eu não acho que isso vai funcionar.
FrVaBe
Isso é útil, exceto quando eu faço um lançamento. Isso substitui ${revision}a tag da versão pela nova versão
Mike D
21

Como Yanflea mencionou, há uma maneira de contornar isso.

No Maven 3.5.0, você pode usar a seguinte maneira de transferir a versão para baixo do projeto pai:

POM.xml pai

<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>

Você pode mudar myversionpara o que quiser, que não seja uma propriedade reservada.

eFox
fonte
3
Ao referenciar um módulo de outro projeto, o Maven não resolve a propriedade. Isso é normal?
LeoLozes 26/02
Acredito que essa pergunta possa ser digna de sua própria entrada e não estar em um comentário como esse. Sem ver seu código, só posso adivinhar.
eFox
@LeoLozes Você resolveu o seu problema (módulo de referência de outro projeto)?
Morteza Malvandi
@MortezaMalvandi yes! Minha resposta está no final :)
LeoLozes 30/01/19
2
O Maven 3.6.0 emite um aviso para esta configuração: "É altamente recomendável corrigir esses problemas porque eles ameaçam a estabilidade da sua compilação." "Por esse motivo, as versões futuras do Maven podem não suportar mais a criação de projetos malformados".
D2k2 6/05/19
18

Você também pode usar:

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

para atualizar os números de versão em seus POMs.

Jerry Jin
fonte
10

A resposta do eFox funcionou para um único projeto, mas não quando eu estava referenciando um módulo de outro (o pom.xml ainda estava armazenado no meu .m2com a propriedade em vez da versão).

No entanto, funciona se você combiná-lo com o flatten-maven-plugin, pois gera os poms com a versão correta, não a propriedade.

A única opção que eu mudei na definição de plug-in é a outputDirectory, ela está vazia por padrão, mas eu prefiro tê-la target, que é definida na minha .gitignoreconfiguração:

<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>

A configuração do plug-in está no pom.xml pai

LeoLozes
fonte
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>

Você quer dizer que deseja remover a versão do bloco pai do pom de B, acho que não pode fazê-lo; groupId, artifactId e version especificaram as coordenadas pom do pai, o que você pode omitir é a versão infantil.

Yu Chai
fonte