233

I'm trying to define a property in our super pom which will be used by all child projects as the destination of the generated artifact.

For this I was thinking about using project/build/finalName yet this does not seem work, even for simple poms:

Command

 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>

And when I executed :

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

I would expect the string "testing" would appear somewhere in the generated artifact name.

Am I misunderstanding the purpose of "finalName" ?

Lii
  • 11,553
  • 8
  • 64
  • 88
Maxim Veksler
  • 29,272
  • 38
  • 131
  • 151
  • 1
    Nice to know - all the defaults (including the final name) are inherited from the Super Pom (and is a good reference source) - http://books.sonatype.com/mvnref-book/reference/pom-relationships-sect-pom.html#pom-relationships-sect-super-pom – Andrejs Dec 18 '17 at 19:31

10 Answers10

417

For Maven >= 3

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

See bug report/documentation.

(Credits to Matthew's and his comment)

For older Maven versions

You set the finalName property in the plugin configuration section:

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

As indicated in the official documentation.

radistao
  • 14,889
  • 11
  • 66
  • 92
Christian Vielma
  • 15,263
  • 12
  • 53
  • 60
  • 4
    Can you specify the "finalName" at the command line? (-Djar.finalName=x) does not appear to work. – jayunit100 Jul 31 '13 at 19:27
  • I haven't tried using the command line. Have you tried the Maven solution? – Christian Vielma Aug 01 '13 at 15:40
  • 1
    A bit of an update, 2.4 is the latest version. Still works fine though. – PaulBGD Aug 17 '14 at 20:21
  • 2
    With Maven plugins one does not have to include version. I assume it picks the latest. And if someone has wondered, the jar name is *without* file suffix, so **no** "myJar.jar" but "myJar" as it is correctly shown in the example. – Espinosa Oct 11 '15 at 16:28
  • @jayunit100 see http://stackoverflow.com/questions/25916249/deploying-a-maven-version-to-github-using-travis-ci/25949705#25949705 for an example on how to make it possible to set the final name on the command line – Reto Gmür Oct 23 '15 at 17:27
  • 18
    As of version 3.0.0 the ``finalName`` configuration has been removed. However the OP's method should work. See https://issues.apache.org/jira/browse/MJAR-233 – Matthew Aug 09 '16 at 08:40
  • What about the final name for a dependency - in my case a dependency *.so is renamed by maven *.jar during goal dependency:copy-dependencies. how do I specify the dep file name to force the so extension? – NicolasW Jun 21 '18 at 15:47
  • @jayunit100 you would need to specify ${finalName} in the pluggin and create a parameter to give finalName a default value. – GetBackerZ Aug 01 '19 at 13:26
  • Adding a finalName, configuration tag also works for the maven-shade-plugin – Bill Naylor Jan 14 '20 at 12:13
  • Can you give more info @OrangeDog? I'm not seeing this with Maven 3.9.1 on Windows. I do see them discussion that error message in [MASSEMBLY-843](https://issues.apache.org/jira/browse/MASSEMBLY-843), but that seems to relate to the Maven Assembly Plugin configuraiton, not ``. Maybe you're talking about the older plugin configuration approach? – Garret Wilson Apr 01 '23 at 21:25
60

All of the provided answers are more complicated than necessary. Assuming you are building a jar file, all you need to do is add a <jar.finalName> tag to your <properties> section:

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

This will generate a jar:

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

This is in the documentation - note the User Property:

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

Command Line Usage

You should also be able to use this option on the command line with:

mvn -Djar.finalName=myCustomName ...

You should get myCustomName.jar, although I haven't tested this.

JBCP
  • 13,109
  • 9
  • 73
  • 111
  • 12
    With Spring Boot this doesn't work as https://stackoverflow.com/a/14490656/2294031. Whereas `foo` creates two jars: an executable jar including dependencies named `foo-${project.version}.jar` and a second jar only containing the project named `${project.name}-${project.version}.jar`, `foo` creates only the executable jar including dependencies named `foo.jar` – domids Jun 30 '17 at 10:03
  • 1
    Works and I agree this is the simple answer and you can even do ${groupId}-${artifactId}-${version} – MG Developer Aug 23 '18 at 01:30
  • I added it to a brand new maven project and it didn't work. It still appends the version number. – alex Oct 01 '20 at 22:31
  • 1
    Doesn't work for Spring Boot. And Spring Boot currently is most popular framework. Micronaut not even close through I hope it will some day. – happy_marmoset Sep 04 '21 at 06:25
47

@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

Output

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


Reference

Jean-Rémy Revy
  • 5,607
  • 3
  • 39
  • 65
dira
  • 30,304
  • 14
  • 54
  • 69
  • 6
    in my case, had to be ${build.directory}/${project.build.finalName}.${project.packaging} – Cpt. Senkfuss Aug 23 '13 at 12:23
  • 2
    What's the difference between putting the finalName tag directly in the maven-install-plugin VS maven-jar-plugin? – Pocketkid2 Aug 24 '15 at 18:21
  • This is great, I was able to use this trick to publish an .xml file directly as an artifact. – Benjamin Damm May 19 '16 at 22:53
  • 1
    It's first building base-1.0.0.SNAPSHOT.jar and then base-4.0.8.8.jar ? – Mark W Jul 07 '16 at 08:41
  • 1
    Why is the artifact installed twice with two different names? Please show a configuration to install it just once. – chrisinmtown Feb 07 '17 at 18:29
  • 1
    Beware: you might need to specify extension manually instead of using `${project.packaging}` variable (e.g. for `maven-plugin` which generates `.jar` file) – izogfif Jan 14 '19 at 08:25
  • This answer helped me a lot. In my case, without customizing the `maven-install-plugin`, the JAR file would appear with the custom name in the `target` folder but was installed into the local repository with the original name. I also needed to specify the `classifier` in my `maven-install-plugin` configuration. – raner Dec 18 '22 at 14:34
21

At the package stage, the plugin allows configuration of the imported file names via file mapping:

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

If you have configured your version to be 'testing' via a profile or something, this would work for a war package:

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>
Jean-Rémy Revy
  • 5,607
  • 3
  • 39
  • 65
Nichole
  • 211
  • 2
  • 3
13

This works for me

mvn jar:jar -Djar.finalName=custom-jar-name
Oleg Mikhailov
  • 5,751
  • 4
  • 46
  • 54
4

The approach you've been using indeed does jar file with a string 'testing' in its name, as you specified, but the default install command sends it to your ~/.m2/repository directory, as seen in this output line:

/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

It seems to me that you're trying to generate a jar with such name and then copy it to a directory of your choice.

Try using outputDirectory property as described here: http://maven.apache.org/plugins/maven-jar-plugin/jar-mojo.html

Goran Jovic
  • 9,418
  • 3
  • 43
  • 75
  • Actually, my complete setup is the following: I have superpom in which I would like to define the current version I'm building for. Then I have several projects that define this pom as their parent. I use hudson-ci to build all these projects. Then hudson pushed the projects into artifactory. I'm seeking something that would allow me to change the version that is currently being built. I will have a look at how I can use your new input. Thank you. – Maxim Veksler Nov 21 '10 at 17:26
  • So... in order to control the version that will be installed I need to override a different maven parameter? – Maxim Veksler Nov 21 '10 at 17:28
  • 7
    That's not correct. The name in the local repo is normalized: `groupId/artifactId/version/artifactId-version-classifier.packaging`. finalName only applies to the local file name in the output directory. – Sean Patrick Floyd Nov 21 '10 at 18:48
  • Thanks for noticing. Actually, the very line I quoted shows my error. However, I got the impression that what Maxim needed was the jar in local directory (of his choice). – Goran Jovic Nov 21 '10 at 20:38
  • @SeanPatrickFloyd so is there any way to change artifactId-version-classifier.packaging to cutom name ? – Khalid Abu El-Soud Dec 11 '14 at 13:17
  • @KhalidAbuEl-Soud not in the repository, no. and that's a good thing, because changing that name convention would break maven dependency management. maven knows exactly what URL to use to retrieve what dependency, based on these parameters, as long as the server stores the artifacts according to these conventions – Sean Patrick Floyd Dec 11 '14 at 13:28
3

I am using the following

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

This way you can define each value individually or pragmatically from Jenkins of some other system.

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

This will place a folder target\{group.id}\projectName-1.2.3.jar

A better way to save time might be

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

Like the same except I use on variable.

  mvn package -DbaseVersion=0.3.4

This will place a folder target\{group.id}\projectName-1.2.3.jar

you can also use outputDirectory inside of configuration to specify a location you may want the package to be located.

GetBackerZ
  • 448
  • 5
  • 12
2

In my maven ee project I am using:

<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
  • 3,675
  • 3
  • 34
  • 37
1

The simplest solution:

<artifactId>Example</artifactId>
<version>1.0</version>

<properties>
    <jarName>${project.artifactId}-${project.version}</jarName>
</properties>

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

Which results in:

mvn clean package -DjarName=123 -> target/123.jar

mvn clean package -> target/Example.jar

Georgi Peev
  • 912
  • 1
  • 14
  • 25
0

I reckon the easiest way is to add <finalName>jar_name<finalName>. It should look like this where in this case I wanted my jar file to be called springboot-mysql:

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <finalName>springboot-mysql</finalName>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
Han
  • 407
  • 2
  • 5
  • 16