我在构建maven项目时遇到了问题。我需要生成 deterministic jar文件,如果这些版本之间没有源代码更改,则必须在不同版本和版本之间保持二进制一致。为此,我使用this article作为指导。
我已经成功地建立了我的罐子,它们符合我的要求。这是我的配置:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>step-1-remove-timestamp</id>
<phase>prepare-package</phase>
<configuration>
<target>
<touch datetime="01/01/2015 00:10:00 am">
<fileset dir="target/classes"/>
<fileset dir="src"/>
</touch>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>step-3-rename-assembly</id>
<phase>package</phase>
<configuration>
<target>
<copy file="${project.build.directory}/${project.build.finalName}-deterministic.zip"
tofile="${project.build.directory}/${project.build.finalName}.jar"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/zip.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>step-2-make-assembly</id>
<phase>prepare-package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
在上面的代码中,我将jar构建并打包为zip,然后将zip复制到预期的jar工件上
上面的问题是,maven仍然执行maven-jar-plugin
,因此手动组装的jar被maven-jar-plugin
之一覆盖。我不想使用这个jar,因为它不符合我的要求。
所以,我已经禁用了maven-jar-plugin
执行,明确将其设置为运行无效阶段,如下所示:(从other posts here看到)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-jar</id>
<phase>never</phase>
<configuration>
<finalName>unwanted</finalName>
<classifier>unwanted</classifier>
</configuration>
</execution>
</executions>
</plugin>
一切似乎都很好,直到我发现我的主jar工件从未安装在.m2
目录中。为了解决这个问题,我还添加了maven-helper-plugin
,以便我手动附加我从汇编程序插件中生成的任何工件:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<id>attach-instrumented-jar</id>
<phase>verify</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.build.finalName}.jar</file>
<type>jar</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
这会导致我无法解决的错误:
[错误]无法在项目my-project上执行目标org.codehaus.mojo:build-helper-maven-plugin:1.9.1:attach-artifact(attach-instrumented-jar):执行attach-instrumented-jar目标org.codehaus.mojo:build-helper-maven-plugin:1.9.1:attach-artifact failed:对于工件{full-name-of-my-project.jar}:附件工件必须有与其对应的主要工件不同的ID。 - &gt; [帮助1]
有没有办法克服这个问题?我已经检查了解决方案,并且大多数建议使用分类器,但我想像maven-jar-plugin
一样安装主工件。我们正在开发的其他软件将需要标准的jar依赖,我们希望通过不合理地引入分类器来避免使我们的设置复杂化。
答案 0 :(得分:3)
经过一些试验和失败后,我碰巧找到了一个有效的解决方案。 我在这里发布它的希望是有用的,或者有任何问题指向我,因为我不确定这是否是一种可靠的方法。
所以,我收到的错误
附加工件必须具有与其对应的主工件不同的ID。
对我来说意味着我无法手动安装“再次”主要工件。由于maven-jar-plugin
不再生成该工件,因此即使存在该文件,也永远不会安排安装(antrun复制任务会生成具有相同名称的jar)。
令人惊讶的是,它需要一些小技巧才能使这项工作再次发挥作用:
重新启用maven-jar-plugin
,因为它应该是:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
</execution>
</executions>
</plugin>
这将在package
阶段生成标准jar,最重要的是,让maven知道在install
阶段安装它。
使用确定性zip将maven-antrun-plugin
复制任务调整为覆盖已生成的jar。设置几乎与我的问题相同,所以我只是添加了差异:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>...</execution>
<execution>
<id>step-3-rename-assembly-and-sources</id>
<phase>package</phase>
<configuration>
<target>
<copy file="${project.build.directory}/${project.build.finalName}-deterministic.zip"
tofile="${project.build.directory}/${project.build.finalName}.jar"
overwrite="true"/>
</target>
</configuration>
</execution>
. . .
</executions>
</plugin>
复制操作现在已指定overwrite="true"
。最初,复制操作似乎忽略了目标中的文件(如果它们已经存在),并且发生的事情是maven-jar-plugin
在复制发生时已经产生了默认的jar工件。设置此选项后,maven-antrun-plugin
现在覆盖具有确定性jar的前jar,后者成为maven install
阶段的主题。
从build-helper-maven-plugin中删除了设置,以便第二次不复制主jar工件:
<击> 撞击>
<击>
<artifact>
<file>${project.build.directory}/${project.build.finalName}.jar</file>
<type>jar</type>
</artifact>
击> <击> 撞击>
就是这样,正确的jar安装在.m2
目录中。
答案 1 :(得分:1)
如果您没有插件可以为您创建和附加主要工件,那么Groovy Maven插件还有一个更通用的解决方案:
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>set-main-artifact</id>
<phase>package</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
project.artifact.setFile(new File(project.build.directory, project.build.finalName + ".zip"))
</source>
</configuration>
</execution>
</executions>
</plugin>
受https://stackoverflow.com/a/31513690/2053580帖子https://stackoverflow.com/users/1314907/lukasz-guminski的启发