java - 如果由 maven-assembly-plugin 构建,则手动附加主要工件

标签 java maven-3 maven-assembly-plugin

我在构建 Maven 项目时遇到问题。我需要生成确定性 jar 文件,这些文件必须在不同的构建和版本之间保持二进制一致,以防这些构建之间没有源代码更改。为此,我使用了 this article寻求指导。

我已经成功地构建了我的 jar ,它们符合我的要求。这是我的配置:

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

这会导致我无法解决的错误:

[ERROR] Failed to execute goal org.codehaus.mojo:build-helper-maven-plugin:1.9.1:attach-artifact (attach-instrumented-jar) on project my-project: Execution attach-instrumented-jar of goal org.codehaus.mojo:build-helper-maven-plugin:1.9.1:attach-artifact failed: For artifact {full-name-of-my-project.jar}: An attached artifact must have a different ID than its corresponding main artifact. -> [Help 1]

有没有办法解决这个问题?我已经检查了解决方案,大多数建议使用分类器,但我想像安装 maven-jar-plugin 一样安装主要工件。我们正在开发的其他软件将需要标准的 jar 依赖项,我们希望避免通过不合理地引入分类器使我们的设置复杂化。

最佳答案

经过更多的尝试和失败后,我碰巧提出了一个可行的解决方案。 我将它张贴在这里,希望它有用,或者有任何问题可以指出我,因为我不确定这是否是一种可靠的方法。

所以,我收到的错误

An attached artifact must have a different ID than its corresponding main artifact.

对我来说意味着我不能手动“再次”安装主要工件。由于 maven-jar-plugin 不再生产该工件,即使文件存在,它也永远不会安排安装(antrun 复制任务会生成一个同名的 jar)。

令人惊讶的是,它需要一些小技巧才能再次运行:

  1. 重新启用 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 期间安装阶段。

  2. 调整 maven-antrun-plugin复制任务以使用确定性 zip 覆盖已经生成的 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阶段。

  3. 从 build-helper-maven-plugin 中删除了设置,这样主 jar 工件就不会被第二次复制:

<罢工>

<罢工>

            <artifact>
              <file>${project.build.directory}/${project.build.finalName}.jar</file>
              <type>jar</type>
            </artifact>

<罢工>

就是这样,正确的 jar 安装在 .m2 中目录。

关于java - 如果由 maven-assembly-plugin 构建,则手动附加主要工件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28156049/

相关文章:

java - 在java中将A字节转换为ASCII字符

java - 如何设置maven 3本地插件仓库

java - 在 maven 中使用/导入本地 fat jar 作为插件

java - maven安装时出现‘系统找不到指定的路径’错误

java - 在多模块项目上构建一个 "light"jar

java - 使用查询字符串的 ReSTLet 路由

java - 显示来自SD卡的jpg android

java - 递归使用模块化算术解释java

maven - 在 Maven 中,如何递归地构建文件系统中但 react 器外部存在的 -SNAPSHOT 依赖项?