在组装后但在安装之前对 jar 进行后处理(以获得幂等构建)

2022-09-04 23:19:14

我们使用 Jenkins,它使用 md5 指纹识别来识别工件,以及自上次构建以来工件是否发生了变化。不幸的是,Maven构建总是生成二进制不同的工件。

因此,我正在考虑让 Maven 为同一组输入文件生成相同的 jar 工件,无论它们在何时何地构建,这意味着 jar 文件中的条目必须进行排序 - 不仅在索引中,而且在写入 jar 文件的顺序中。

在检查了使用maven-assembly-plugin的maven-jar-plugin之后,我的结论是,在一次写入所有文件之前,它们不会收集所有要写入内存的文件,而是一次写入一个。这意味着最好对生成的 jar 进行后处理,而不是更改当前行为,这样我就可以对条目进行排序,将时间戳归零等。

我不熟悉编写Maven插件,所以我的问题是,我应该如何编写一个插件,Maven知道如何判断正在进行的工件罐的位置以及我如何将其连接到我的pom.xml?

(起初我需要这个来处理jar文件,但war文件也会很好)。


答案 1

如前所述,这可以基于类似于 .我继续编写了一个简单的插件来添加此功能 - 请参阅 https://github.com/manouti/jar-timestamp-normalize-maven-plugin(在中央存储库中可用)。maven-shade-plugin

该行为基于插件。它由一个名为的目标组成,该目标可以绑定到生命周期阶段并在项目的POM中进行配置:shadenormalizepackage

<plugins>
    <plugin>
        <groupId>com.github.manouti</groupId>
        <artifactId>jar-timestamp-normalize-maven-plugin</artifactId>
        <version>1.0-SNAPSHOT</version>
        <executions>
            <execution>
                <id>jar-normalize</id>
                <goals>
                    <goal>normalize</goal>
                </goals>
                <phase>package</phase>
            </execution>
        </executions>
    </plugin>
</plugins>

关于插件的一些注意事项:

  1. 正在构建的项目通过 where 是 访问的。project#getArtifact()projectorg.apache.maven.project.MavenProject

  2. 规范化主要包括三个步骤:

    • 将所有 Jar 条目的上次修改时间设置为特定时间戳(默认值为,但可以通过系统属性进行更改)。1970-01-01 00:00:00AM-Dtimestamp

    • 对清单中的属性进行重新排序(按字母顺序),但始终排在第一位的属性除外。Manifest-Version

    • 从文件中删除包含时间戳的注释,该时间戳会导致 Jar 因版本而异。pom.properties

调用后,目标将在原始工件(名为 )旁边生成输出文件,即在目录中。artifactId-version-normalized.jarproject.build.directory


答案 2

创建 maven 插件项目

mvn archetype:generate \
  -DgroupId=sample.plugin \
  -DartifactId=hello-maven-plugin \
  -DarchetypeGroupId=org.apache.maven.archetypes \
  -DarchetypeArtifactId=maven-archetype-plugin

调用此命令,它将生成一个框架项目,其类名为MyMojo.java

在方法中编写你的东西,并通过以下方式将该插件安装到你的存储库中execute()mvn clean install

然后将其执行与您的项目附加到您的项目中,在您的项目中pom.xml

 <build>
    <plugins>
      <plugin>
        <groupId>sample.plugin</groupId>
        <artifactId>hello-maven-plugin</artifactId>
        <version>1.0-SNAPSHOT</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>sayhi</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

以访问 Mojo 中的项目属性

    /**
     * The Maven project.
     *
     * @parameter expression="${project}"
     * @required
     * @readonly
     */
    private MavenProject        project; 

然后

project.getProperties("build.directory") 

读取其他属性以确定 jar 文件是否打包



推荐