Kontrolowanie ostatecznej nazwy artefaktu jar

174

Próbuję zdefiniować właściwość w naszym super pomie, która będzie używana we wszystkich projektach podrzędnych jako miejsce docelowe wygenerowanego artefaktu.

Do tego myślałem o użyciu, project/build/finalNameale to nie wydaje się działać, nawet dla prostych pomponów:

Komenda

 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>

A kiedy wykonałem:

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

Spodziewałbym się, że gdzieś w nazwie wygenerowanego artefaktu pojawi się napis „testing”.

Czy źle rozumiem cel „finalName”?

Maxim Veksler
źródło
Warto wiedzieć - wszystkie ustawienia domyślne (w tym ostateczna nazwa) są odziedziczone po Super Pom (i jest dobrym źródłem odniesienia) - books.sonatype.com/mvnref-book/reference/ ...
Andrejs

Odpowiedzi:

291

finalNameWłaściwość ustawiasz w sekcji konfiguracji wtyczki:

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

Jak wskazano w oficjalnej dokumentacji .

Aktualizacja:

Dla Maven> = 3

Na podstawie komentarza Matthew możesz teraz zrobić to w następujący sposób:

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

Zobacz raport o błędzie / dokumentację .

Christian Vielma
źródło
2
Czy możesz określić „finalName” w wierszu poleceń? (-Djar.finalName = x) nie działa.
jayunit100
Nie próbowałem używać wiersza poleceń. Czy wypróbowałeś rozwiązanie Maven?
Christian Vielma
1
Trochę aktualizacji, 2.4 to najnowsza wersja. Jednak nadal działa dobrze.
PaulBGD
1
Dzięki wtyczkom Maven nie trzeba dołączać wersji. Zakładam, że wybiera najnowsze. A jeśli ktoś się zastanawiał, nazwa jar jest bez rozszerzenia pliku, więc nie „myJar.jar”, ​​ale „myJar”, jak jest to poprawnie pokazane w przykładzie.
Espinosa
13
W wersji 3.0.0 finalNamekonfiguracja została usunięta. Jednak metoda PO powinna działać. Zobacz issue.apache.org/jira/browse/MJAR-233
Matthew
42

Wszystkie podane odpowiedzi są bardziej skomplikowane niż to konieczne. Zakładając, że tworzysz plik jar, wszystko, co musisz zrobić, to dodać <jar.finalName>tag do swojej <properties>sekcji:

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

Spowoduje to wygenerowanie słoika:

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

To jest w dokumentacji - zwróć uwagę na User Property:

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

Wykorzystanie wiersza poleceń

Powinieneś także móc użyć tej opcji w wierszu poleceń z:

mvn -Djar.finalName=myCustomName ...

Powinieneś pobrać myCustomName.jar, chociaż nie testowałem tego.

JBCP
źródło
6
W przypadku Spring Boot nie działa to jako stackoverflow.com/a/14490656/2294031 . Podczas gdy <jar.finalName>foo</jar.finalName>tworzy dwa pliki jar: wykonywalny plik jar zawierający zależności o nazwie foo-${project.version}.jari drugi plik jar zawierający tylko projekt o nazwie ${project.name}-${project.version}.jar, <build><finalName>foo</finalName></build>tworzy tylko plik jar wykonywalny zawierający zależności o nazwiefoo.jar
Snozzlebert
Działa i zgadzam się, że to prosta odpowiedź i możesz nawet wykonać <jar.finalName> $ {groupId} - $ {artifactId} - $ {version} </ jar.finalName>
MG Developer
37

@Maxim
spróbuj tego ...

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

Wynik

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


Odniesienie

dira
źródło
5
w moim przypadku <file> musiał być <file> $ {build.directory} / $ {project.build.finalName}. $ {project.packaging} </file>
Cpt. Senkfuss
2
Jaka jest różnica między umieszczeniem tagu finalName bezpośrednio w maven-install-plugin VS maven-jar-plugin?
Pocketkid2
To świetnie, udało mi się użyć tej sztuczki do opublikowania pliku .xml bezpośrednio jako artefaktu.
Benjamin Damm
1
Najpierw tworzy plik base-1.0.0.SNAPSHOT.jar, a następnie base-4.0.8.8.jar?
Mark W
1
Dlaczego artefakt jest instalowany dwukrotnie pod dwoma różnymi nazwami? Pokaż konfigurację, aby zainstalować ją tylko raz.
chrisinmtown,
18

Na etapie pakietu wtyczka umożliwia konfigurację importowanych nazw plików poprzez mapowanie plików:

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

Jeśli skonfigurowałeś swoją wersję do `` testowania '' za pośrednictwem profilu lub czegoś podobnego, zadziała to dla pakietu wojennego:

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
źródło
1
A do archiwum słoików?
Stephane
8

To działa dla mnie

mvn jar:jar -Djar.finalName=custom-jar-name
Oleg Michajłow
źródło
3

Podejście, z którego korzystałeś, rzeczywiście powoduje, że plik jar zawiera w nazwie ciąg `` testing '', tak jak to określiłeś, ale domyślne polecenie instalacji wysyła go do katalogu ~ / .m2 / repository, jak widać w tym wierszu wyjściowym:

/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

Wydaje mi się, że próbujesz wygenerować jar o takiej nazwie, a następnie skopiować go do wybranego katalogu.

Spróbuj użyć właściwości outputDirectory, jak opisano tutaj: http://maven.apache.org/plugins/maven-jar-plugin/jar-mojo.html

Goran Jovic
źródło
Właściwie moja kompletna konfiguracja jest następująca: Mam superpom, w którym chciałbym zdefiniować bieżącą wersję, dla której tworzę. Następnie mam kilka projektów, w których ten pom jest ich rodzicem. Do tworzenia wszystkich tych projektów używam hudson-ci. Następnie Hudson wepchnął projekty w sztuczną fabrykę. Szukam czegoś, co pozwoliłoby mi zmienić wersję, która jest obecnie budowana. Rzucę okiem, jak mogę wykorzystać nowe dane wejściowe. Dziękuję Ci.
Maxim Veksler
Więc ... aby kontrolować wersję, która zostanie zainstalowana, muszę nadpisać inny parametr maven?
Maxim Veksler
7
To nie jest poprawne. Nazwa w lokalnym repo normalizuje: groupId/artifactId/version/artifactId-version-classifier.packaging. finalName dotyczy tylko lokalnej nazwy pliku w katalogu wyjściowym.
Sean Patrick Floyd
Dzięki, że zauważyłeś. Właściwie to sama linia, którą zacytowałem, pokazuje mój błąd. Jednak odniosłem wrażenie, że Maxim potrzebował słoika w lokalnym katalogu (według własnego wyboru).
Goran Jovic
@SeanPatrickFloyd, więc czy istnieje sposób na zmianę artifactId-version-classifier.packaging na nazwę cutom?
Khalid Abu El-Soud,
2

Używam następujących

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

W ten sposób możesz zdefiniować każdą wartość indywidualnie lub pragmatycznie z Jenkinsa innego systemu.

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

Spowoduje to umieszczenie folderu target\{group.id}\projectName-1.2.3.jar

Może być lepszym sposobem na zaoszczędzenie czasu

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

Podobnie jak to samo, z wyjątkiem tego, że używam zmiennej.

  mvn package -DbaseVersion=0.3.4

Spowoduje to umieszczenie folderu target\{group.id}\projectName-1.2.3.jar

możesz również użyć outputDirectorywewnątrz, configurationaby określić lokalizację, w której pakiet ma się znajdować.

GetBackerZ
źródło
1

W moim projekcie maven ee używam:

<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
źródło