Manually attach the main artifact if it is built using the maven-assembly-plugin

I am having problems creating a maven project. I have a requirement to create deterministic jar files that must be binary consistent across builds and versions if there are no source code changes between these builds. For this purpose, I used this article as a guide.

I managed to create my own banks, and they meet my requirements. Here is my configuration:

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

In the above code, I create and pack the jar as a zip, and then copy the zip over the expected jar artifact.
The problem with the above is that maven is still executing maven-jar-plugin , so a manually assembled jar is overwritten by one of the maven-jar-plugin . I do not want to use this jar because it does not meet my requirements.

So, I turned off the maven-jar-plugin execution, explicitly setting it to work with an invalid phase, as shown below: (saw that from 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> 

Everything seems fine until I discovered that my main artifact is not installed in the .m2 directory. To fix this, I also added a maven-helper-plugin to manually bind any artifacts that I create from the assembler 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> 

This results in an error that I cannot solve:

[ERROR] Failed to complete org.codehaus.mojo: build-helper-maven-plugin: 1.9.1: attach-artifact (attach-instrumented-jar) target in my-project: Execution attach-instrumented-jar project to org target. codehaus.mojo: build-helper-maven-plugin: 1.9.1: attach-artefact failed: for artifact {full-name-of-my-project.jar}: The attached artifact must be different from the corresponding main artifact. โ†’ [Help 1]

Is there any way to overcome this problem? I checked the solutions and most recommend using classifiers, but I want to install the main artifact, like the maven-jar-plugin . Other software that we are developing will require a standard jar dependency, and we want to avoid complicating our installation by introducing classifiers unreasonably.

+7
source share
2 answers

After several trials and failures, I got a working solution. I post it here, hoping to be either helpful or have any problems pointing to me, as I'm not sure if this is a reliable approach.

So, the error I received

The attached artifact must have a different identifier than the corresponding artifact.

meant that I canโ€™t manually set the main artifact โ€œagainโ€. Since this artifact is no longer created by maven-jar-plugin , it will never be scheduled for installation, even if the file is present (the task of copying the antran creates a jar with the same name).

Surprisingly, this took a few small tricks:

  • Re-enabled maven-jar-plugin , as it should be:

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

    This will create a standard jar in the package phase and, most importantly, make maven to install it during the install phase.

  • Change the maven-antrun-plugin copy task to overwrite an already created jar with a deterministic zip code. The setup is almost identical, as in my question, so I only add the differences:

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

    Now the copy operation has overwrite="true" . Initially, the copy operation seemed to ignore the files at the destination, if they already exist, and it happened that the maven-jar-plugin already produced the default jar artifact when the copy occurred. With this option, maven-antrun-plugin now redefines the first jar with a deterministic one, and the latter becomes the subject of the maven install phase.

  • The configuration has been removed from the build-helper-maven-plugin module, so the main jar artifact is not copied a second time:

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

Strike>

What is it, the correct jar is installed in the .m2 directory.

+3
source

If you do not have a plugin to create and attach the main artifact for you, there is a more general solution with the Groovy Maven plugin:

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

Inspired by the mail fooobar.com/questions/591491 / ... thanks a lot https://stackoverflow.com/users/1314907/lukasz-guminski

0
source

Source: https://habr.com/ru/post/981567/


All Articles