Controlando o nome final do maven do artefato jar


174

Estou tentando definir uma propriedade em nosso super pom que será usada por todos os projetos filhos como destino do artefato gerado.

Para isso, eu estava pensando em usar project/build/finalNameainda isso não parece funcionar, mesmo para poms simples:

Comando

 mvn archetype:create \ 
   -DarchetypeGroupId=org.apache.maven.archetypes \
   -DgroupId=com.mycompany.app \
   -DartifactId=my-app

POM

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>my-app</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <build>
        <finalName>${project.name}-testing</finalName>
  </build>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

E quando eu executei:

$ mvn install

[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building my-app
[INFO]    task-segment: [install]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources {execution: default-resources}]
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /tmp/mvn_test/my-app/src/main/resources
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources {execution: default-testResources}]
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /tmp/mvn_test/my-app/src/test/resources
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [surefire:test {execution: default-test}]
[INFO] Surefire report directory: /tmp/mvn_test/my-app/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.mycompany.app.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.024 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] [jar:jar {execution: default-jar}]
[INFO] [install:install {execution: default-install}]
[INFO] Installing /tmp/mvn_test/my-app/target/my-app-testing.jar to /home/maxim/.m2/repository/com/mycompany/app/my-app/1.0-SNAPSHOT/my-app-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2 seconds
[INFO] Finished at: Sun Nov 21 18:37:02 IST 2010
[INFO] Final Memory: 17M/162M
[INFO] ------------------------------------------------------------------------

Eu esperaria que a string "testing" aparecesse em algum lugar no nome do artefato gerado.

Estou entendendo mal o propósito de "finalName"?


É bom saber - todos os padrões (incluindo o nome final) são herdados do Super Pom (e é uma boa fonte de referência) - books.sonatype.com/mvnref-book/reference/…
Andrejs

Respostas:


291

Você define a finalNamepropriedade na seção de configuração do plug-in:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <finalName>myJar</finalName>                   
    </configuration>
</plugin>       

Conforme indicado na documentação oficial .

Atualizar:

Para Maven> = 3

Com base no comentário de Matthew, agora você pode fazer o seguinte:

 <packaging>jar</packaging>
 <build>
   <finalName>WhatEverYouLikey</finalName>
 </build>

Veja o relatório / documentação do bug .


2
Você pode especificar o "finalName" na linha de comando? (-Djar.finalName = x) não parece funcionar.
jayunit100

Eu não tentei usar a linha de comando. Você já experimentou a solução Maven?
Christian Vielma

1
Um pouco de atualização, 2.4 é a versão mais recente. Ainda funciona bem.
PaulBGD

1
Com os plugins do Maven, não é necessário incluir a versão. Eu suponho que escolhe o mais recente. E se alguém se perguntou, o nome do jar é sem sufixo de arquivo, portanto, não "myJar.jar", mas "myJar", como é mostrado corretamente no exemplo.
Espinosa

13
A partir da versão 3.0.0, a finalNameconfiguração foi removida. No entanto, o método do OP deve funcionar. Veja Issues.apache.org/jira/browse/MJAR-233
Matthew

42

Todas as respostas fornecidas são mais complicadas do que o necessário. Supondo que você esteja criando um arquivo jar, tudo que você precisa fazer é adicionar uma <jar.finalName>tag à sua <properties>seção:

<properties>
    <jar.finalName>${project.name}</jar.finalName>
</properties>

Isso irá gerar um jar:

project/target/${project.name}.jar

Isso está na documentação - observe o User Property:

finalName:
Name of the generated JAR.
Type: java.lang.String
Required: No
User Property: jar.finalName
Default: ${project.build.finalName}

Uso da linha de comando

Você também deve poder usar esta opção na linha de comando com:

mvn -Djar.finalName=myCustomName ...

Você deve obter myCustomName.jar, embora eu não tenha testado isso.


6
Com o Spring Boot, isso não funciona como stackoverflow.com/a/14490656/2294031 . Considerando <jar.finalName>foo</jar.finalName>cria dois frascos: um jar executável incluindo dependências nomeados foo-${project.version}.jare um segundo frasco contendo apenas o projeto chamado ${project.name}-${project.version}.jar, <build><finalName>foo</finalName></build>cria apenas o jar executável incluindo dependências chamadofoo.jar
Snozzlebert

Funciona e eu concordo que esta é a resposta simples e você pode até fazer <jar.finalName> $ {groupId} - $ {artifactId} - $ {version} </ jar.finalName>
MG Developer

37

@Maxim
try this ...

pom.xml

 <groupId>org.opensource</groupId>
 <artifactId>base</artifactId>
 <version>1.0.0.SNAPSHOT</version>

  ..............
<properties>
    <my.version>4.0.8.8</my.version>
</properties>

<build>
    <finalName>my-base-project</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-install-plugin</artifactId>
            <version>2.3.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>install-file</goal>
                    </goals>
                    <phase>install</phase>
                    <configuration>
                        <file>${project.build.finalName}.${project.packaging}</file>
                        <generatePom>false</generatePom>
                        <pomFile>pom.xml</pomFile>
                        <version>${my.version}</version>
                    </configuration>
                </execution>
            </executions>
        </plugin>
</plugins>
</build>

Commnad mvn clean install

Resultado

[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ base ---
[INFO] Building jar: D:\dev\project\base\target\my-base-project.jar
[INFO]
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ base ---
[INFO] Installing D:\dev\project\base\target\my-base-project.jar to H:\dev\.m2\repository\org\opensource\base\1.0.0.SNAPSHOT\base-1.0.0.SNAPSHOT.jar
[INFO] Installing D:\dev\project\base\pom.xml to H:\dev\.m2\repository\org\opensource\base\1.0.0.SNAPSHOT\base-1.0.0.SNAPSHOT.pom
[INFO]
[INFO] --- maven-install-plugin:2.3.1:install-file (default) @ base ---
[INFO] Installing D:\dev\project\base\my-base-project.jar to H:\dev\.m2\repository\org\opensource\base\4.0.8.8\base-4.0.8.8.jar
[INFO] Installing D:\dev\project\base\pom.xml to H:\dev\.m2\repository\org\opensource\base\4.0.8.8\base-4.0.8.8.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------


Referência


5
no meu caso, <file> tinha que ser <file> $ {build.directory} / $ {project.build.finalName}. $ {project.packaging} </file>
Cpt. Senkfuss

2
Qual é a diferença entre colocar a tag finalName diretamente no maven-install-plugin VS maven-jar-plugin?
precisa saber é o seguinte

Isso é ótimo, eu pude usar esse truque para publicar um arquivo .xml diretamente como um artefato.
Benjamin Damm

1
É o primeiro edifício base-1.0.0.SNAPSHOT.jar e depois base-4.0.8.8.jar?
Mark W

1
Por que o artefato é instalado duas vezes com dois nomes diferentes? Por favor, mostre uma configuração para instalá-lo apenas uma vez.
Chrisinmtown 7/02

18

No estágio do pacote, o plug-in permite a configuração dos nomes de arquivos importados por meio do mapeamento de arquivos:

maven-ear-plugin

http://maven.apache.org/plugins/maven-ear-plugin/examples/customize-file-name-mapping.html

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-ear-plugin</artifactId>
    <version>2.7</version>
    <configuration>
       [...]
        <fileNameMapping>full</fileNameMapping>
    </configuration>
</plugin>

http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html#outputFileNameMapping

Se você configurou sua versão para 'testar' através de um perfil ou algo assim, isso funcionaria para um pacote war:

maven-war-plugin

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.2</version>
    <configuration>
        <encoding>UTF-8</encoding>                        
        <outputFileNameMapping>@{groupId}@-@{artifactId}@-@{baseVersion}@@{dashClassifier?}@.@{extension}@</outputFileNameMapping>
    </configuration>
</plugin>

1
E para um arquivo jar?
Stephane


3

A abordagem que você está usando de fato faz o arquivo jar com uma string 'testing' em seu nome, como você especificou, mas o comando de instalação padrão o envia para o diretório ~ / .m2 / repository, como visto nesta linha de saída:

/tmp/mvn_test/my-app/target/my-app-testing.jar to /home/maxim/.m2/repository/com/mycompany/app/my-app/1.0-SNAPSHOT/my-app-1.0-SNAPSHOT.jar

Parece-me que você está tentando gerar um jar com esse nome e copiá-lo para um diretório de sua escolha.

Tente usar a propriedade outputDirectory conforme descrito aqui: http://maven.apache.org/plugins/maven-jar-plugin/jar-mojo.html


Na verdade, minha configuração completa é a seguinte: Tenho superpom no qual gostaria de definir a versão atual para a qual estou construindo. Então, tenho vários projetos que definem esse pom como pai. Eu uso o hudson-ci para construir todos esses projetos. Hudson empurrou os projetos para artefatos. Estou procurando algo que me permita alterar a versão que está sendo construída no momento. Vou dar uma olhada em como posso usar sua nova entrada. Obrigado.
precisa

Então ... para controlar a versão que será instalada, preciso substituir um parâmetro diferente do maven?
precisa

7
Isso não está correto. O nome no repo local está normalizada: groupId/artifactId/version/artifactId-version-classifier.packaging. finalName se aplica apenas ao nome do arquivo local no diretório de saída.
Sean Patrick Floyd

Obrigado por perceber. Na verdade, a própria linha que citei mostra meu erro. No entanto, tive a impressão de que o Maxim precisava era do jar no diretório local (de sua escolha).
precisa

@SeanPatrickFloyd, existe alguma maneira de alterar artifactId-version-classifier.packaging para cutom name?
Khalid Abu El-Soud

2

Eu estou usando o seguinte

        ....
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.0.2</version>
            <configuration>
                <finalName>${project.groupId}/${project.artifactId}-${baseVersion}.${monthlyVersion}.${instanceVersion}</finalName>
            </configuration>
        </plugin>
        ....

Dessa forma, você pode definir cada valor individual ou pragmaticamente no Jenkins de outro sistema.

mvn package -DbaseVersion=1 -monthlyVersion=2 -instanceVersion=3

Isso colocará uma pasta target\{group.id}\projectName-1.2.3.jar

Uma maneira melhor de economizar tempo pode ser

        ....
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.0.2</version>
            <configuration>
                <finalName>${project.groupId}/${project.artifactId}-${baseVersion}</finalName>
            </configuration>
        </plugin>
        ....

Como o mesmo, exceto que eu uso na variável.

  mvn package -DbaseVersion=0.3.4

Isso colocará uma pasta target\{group.id}\projectName-1.2.3.jar

você também pode usar outputDirectorydentro de configurationpara especificar um local em que você deseja que o pacote seja localizado.


1

No meu projeto do maven ee, estou usando:

<build>
    <finalName>shop</finalName>

    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>${maven.war.version}</version>
            <configuration><webappDirectory>${project.build.directory}/${project.build.finalName}     </webappDirectory>
            </configuration>
        </plugin>
    </plugins>
</build>
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.