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

Maxim Veksler
fonte
É 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 .

Christian Vielma
fonte
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.

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

dira
fonte
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>
Nichole
fonte
1
E para um arquivo jar?
Stephane
8

Isso funciona para mim

mvn jar:jar -Djar.finalName=custom-jar-name
Oleg Mikhailov
fonte
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

Goran Jovic
fonte
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.

GetBackerZ
fonte
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>
Mircea Stanciu
fonte