组装后但安装前的后处理jar(以获得幂等构建)

时间:2014-07-25 17:14:31

标签: java maven build-process

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

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

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

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

(起初我需要这个用于jar文件,但战争文件也会很好。)

4 个答案:

答案 0 :(得分:3)

如上所述,这可以基于类似于maven-shade-plugin的内容来完成。我继续编写了一个简单的插件来添加此功能 - 请参阅https://github.com/manouti/jar-timestamp-normalize-maven-plugin(可在Central repo上找到)。

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

<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. 正在构建的工件可通过project#getArtifact()访问,其中projectorg.apache.maven.project.MavenProject

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

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

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

    • pom.properties文件中删除包含时间戳的注释,该时间戳会导致Jar从一个版本到另一个版本不同。

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

答案 1 :(得分:0)

创建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") 

read other properties确定你的jar文件包装


查看

答案 2 :(得分:0)

我同意创建自定义maven插件似乎是一个更好的选择。我不知道现有的插件为你提出的问题提供了解决方案。

使用安装插件生成md5校验和(或我的存储库中的sha-1),因此您似乎需要对此​​进行扩展或编写一个在安装阶段后工作的新插件。

我对此插件有2条建议:

1)当想到简单时,这个插件应该:

  • 读取生成的jar:
    • 提取所有条目。
    • 排除部分参赛作品(例如MANIFEST.MF)。
    • 对剩余的条目进行排序。
    • 在内存中为每个内容提取md5。
    • 从所有提取的内容中生成一个md5。

然而,考虑到哪里和&amp;独立时:Accordig .class文件结构Java_class_file有小的,主要版本条目保存在已编译的类文件中。因此,如果编译器更改,则会更改.class文件。在这种情况下,我们需要从这一点检查源代码级别:(因此,如果对copiler版本没有保证,此解决方案将变得无用。

2)这个插件非常脏但很容易解决,它只能提取模块的pom.xml文件的 md5 代码。但您必须保证jar中的每个更改都会手动反映为次要版本(或内置编号)。

答案 3 :(得分:0)

您可以编写由groovy-maven-plugin执行的Groovy脚本,而不是编写自己的插件:

$timeCalc = 60