控制 jar 工件的 Maven 最终名称
Posted
技术标签:
【中文标题】控制 jar 工件的 Maven 最终名称【英文标题】:Controlling Maven final name of jar artifact 【发布时间】:2011-05-13 10:37:02 【问题描述】:我正在尝试在我们的超级 pom 中定义一个属性,该属性将被所有子项目用作生成的工件的目的地。
为此,我正在考虑使用 project/build/finalName
但这似乎不起作用,即使对于简单的 poms 也是如此:
命令
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>
当我执行时:
$ 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] ------------------------------------------------------------------------
我希望字符串“testing”会出现在生成的工件名称中。
我是否误解了“finalName”的用途?
【问题讨论】:
很高兴知道 - 所有默认值(包括最终名称)都继承自 Super Pom(并且是一个很好的参考源) - books.sonatype.com/mvnref-book/reference/… 【参考方案1】:我认为最简单的方法是添加<finalName>jar_name<finalName>
。它应该看起来像这样,在这种情况下,我希望我的 jar 文件被称为 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>
【讨论】:
【参考方案2】:对于 Maven >= 3
<packaging>jar</packaging>
<build>
<finalName>WhatEverYouLikey</finalName>
</build>
见bug report/documentation。
(归功于Matthew's 和他的comment)
对于较旧的 Maven 版本
您在插件配置部分设置finalName
属性:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<finalName>myJar</finalName>
</configuration>
</plugin>
如official documentation所示。
【讨论】:
能否在命令行中指定“finalName”? (-Djar.finalName=x) 似乎不起作用。 我没有尝试使用命令行。您是否尝试过 Maven 解决方案? 有点更新,2.4是最新版本。不过仍然可以正常工作。 使用 Maven 插件不必包含版本。我认为它选择了最新的。如果有人想知道,jar 名称是 没有 文件后缀,所以 no "myJar.jar" 而是 "myJar",因为它在示例中正确显示。跨度> 从 3.0.0 版开始,finalName
配置已被删除。但是,OP的方法应该有效。见issues.apache.org/jira/browse/MJAR-233【参考方案3】:
最简单的解决方案:
<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>
结果:
mvn clean package -DjarName=123
-> 目标/123.jar
mvn clean package
-> 目标/Example.jar
【讨论】:
【参考方案4】:我正在使用以下
....
<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>
....
通过这种方式,您可以从其他系统的 Jenkins 中单独或实用地定义每个值。
mvn package -DbaseVersion=1 -monthlyVersion=2 -instanceVersion=3
这将放置一个文件夹target\group.id\projectName-1.2.3.jar
节省时间的更好方法可能是
....
<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>
....
除了我在变量上使用之外,其他都一样。
mvn package -DbaseVersion=0.3.4
这将放置一个文件夹target\group.id\projectName-1.2.3.jar
您还可以在configuration
中使用outputDirectory
来指定您可能希望包所在的位置。
【讨论】:
【参考方案5】:在我正在使用的 maven ee 项目中:
<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>
【讨论】:
【参考方案6】:这对我有用
mvn jar:jar -Djar.finalName=custom-jar-name
【讨论】:
就我而言,我使用了mvn clean package -Djar.finalName=custom-jar-name
【参考方案7】:
所有提供的答案都比必要的复杂。假设您正在构建一个 jar 文件,您需要做的就是在您的 <properties>
部分添加一个 <jar.finalName>
标签:
<properties>
<jar.finalName>$project.name</jar.finalName>
</properties>
这将生成一个 jar:
project/target/$project.name.jar
这是在documentation - 请注意User Property
:
finalName:
Name of the generated JAR.
Type: java.lang.String
Required: No
User Property: jar.finalName
Default: $project.build.finalName
命令行用法
您还应该能够在命令行中使用此选项:
mvn -Djar.finalName=myCustomName ...
你应该得到 myCustomName.jar,虽然我没有测试过。
【讨论】:
对于 Spring Boot,这不能作为 ***.com/a/14490656/2294031 工作。而<jar.finalName>foo</jar.finalName>
创建了两个jar:一个包含名为foo-$project.version.jar
的依赖项的可执行jar 和一个仅包含名为$project.name-$project.version.jar
的项目的第二个jar,<build><finalName>foo</finalName></build>
仅创建包含名为foo.jar
的依赖项的可执行jar
有效,我同意这是简单的答案,您甚至可以这样做 在打包阶段,插件允许通过以下方式配置导入的文件名 文件映射:
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
如果您已通过配置文件或其他方式将您的版本配置为“测试”, 这适用于战争包:
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>
【讨论】:
对于 jar 存档?【参考方案9】:@马克西姆 试试这个...
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>
通讯 mvn clean install
输出
[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
【讨论】:
就我而言,您一直在使用的方法确实会执行名称中包含字符串“testing”的 jar 文件,正如您指定的那样,但默认安装命令会将其发送到您的 ~/.m2/repository 目录,如此输出所示行:
/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
在我看来,您正在尝试生成一个具有该名称的 jar,然后将其复制到您选择的目录中。
尝试使用此处所述的 outputDirectory 属性:http://maven.apache.org/plugins/maven-jar-plugin/jar-mojo.html
【讨论】:
实际上,我的完整设置如下:我有 superpom,我想在其中定义我正在构建的当前版本。然后我有几个项目将这个 pom 定义为它们的父级。我使用 hudson-ci 来构建所有这些项目。然后哈德森将这些项目推向了人工制品。我正在寻找可以让我更改当前正在构建的版本的东西。我将看看如何使用您的新输入。谢谢。 所以...为了控制将要安装的版本,我需要覆盖不同的 maven 参数? 这不正确。本地 repo 中的名称已标准化:groupId/artifactId/version/artifactId-version-classifier.packaging
。 finalName 仅适用于输出目录中的本地文件名。
感谢您的关注。实际上,我引用的那一行显示了我的错误。但是,我的印象是,Maxim 需要的是本地目录中的 jar(由他选择)。
@SeanPatrickFloyd 那么有没有办法将 artifactId-version-classifier.packaging 更改为自定义名称?以上是关于控制 jar 工件的 Maven 最终名称的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 maven-assembly-plugin 设置最终的 jar 名称
在 maven-install-plugin 上保留 maven 工件名称(默认安装)
当工件名称与模块名称不同时,使用 Grab 下载 Ivy 依赖 Jar