Search code examples
javamavenbackwards-compatibility

How to use japicmp to compare between artifacts generated in current and previous build


I was looking for some tool to capture the Java compatibility differences between the artifacts generated in the current and previous build of our project. The tool should be part of our daily CI/CD build.

After some googling, I planned to use japicmp to compare between two SNAPSHOT versions, as I found it was fulfilling my requirements, as well as the project is being maintained well.

I tried with the following POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.rohan</groupId>
<artifactId>TestProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>${project.groupId}:${project.artifactId}</name>

<build>
    <plugins>
        <plugin>
            <groupId>com.github.siom79.japicmp</groupId>
            <artifactId>japicmp-maven-plugin</artifactId>
            <version>0.11.1</version>
            <configuration>
                <oldVersion>                        
                    <dependency>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>${project.artifactId}</artifactId>
                        <version>${project.version}</version>
                        <type>jar</type>                            
                    </dependency>
                </oldVersion>
                <newVersion>
                    <file>
                        <path>${project.build.directory}/${project.artifactId}-${project.version}.${project.packaging}</path>
                    </file>
                </newVersion>                   
            </configuration>
            <executions>
                <execution>
                    <phase>verify</phase>
                    <goals>
                        <goal>cmp</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
</project>

However, during execution, the Maven dependency resolver is fetching the Older version of the artifact from the build target directory, and not from the Local repository, which is eventually causing the Older and Newer version to be the same. Our project only releases the artifacts as SNAPSHOT releases with same version number. Hence I am tied up there...

Can someone please advise me how to go about here? Thanks!

UPDATE

I went around this, by copying the older SNAPSHOT artifact in a different folder, during the initialize phase, and then used the same in japicmp during package phase. Following is my POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.rohan</groupId>
<artifactId>TestProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>${project.groupId}:${project.artifactId}</name>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.0.2</version>
            <executions>
                <execution>
                    <id>copy-old-version</id>
                    <phase>initialize</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>${project.artifactId}</artifactId>
                        <version>${project.version}</version>
                        <type>${project.packaging}</type>
                    </artifactItem>
                </artifactItems>
                <outputDirectory>${project.build.directory}/olderVersion</outputDirectory>
            </configuration>
        </plugin>
        <plugin>
            <groupId>com.github.siom79.japicmp</groupId>
            <artifactId>japicmp-maven-plugin</artifactId>
            <version>0.11.1</version>
            <executions>
                <execution>
                    <phase>verify</phase>
                    <goals>
                        <goal>cmp</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <oldVersion>                        
                    <file>
                        <path>${project.build.directory}/olderVersion/${project.artifactId}-${project.version}.${project.packaging}</path>
                    </file>
                </oldVersion>
                <newVersion>
                    <file>
                        <path>${project.build.directory}/${project.artifactId}-${project.version}.${project.packaging}</path>
                    </file>
                </newVersion>                   
            </configuration>                
        </plugin>
    </plugins>
</build>
</project>

I will really appreciate if someone can advise me a better way, or a better tool which can resolve my purpose. Thanks!


Solution

  • Your point is that you are misusing the meaning of a SNAPSHOT in maven. A SNAPSHOT is a development artifact that is supposed to change frequently and overridden by each build cycle. maven will search for the specified artifact first in your local repository, where it will find your latest version and check for the first time a day the remote respository for a newer SNAPSHOT version. Hence, SNAPSHOTs have a special meaning in maven and shouldn't be used for releases. For more information see here or here.

    The maven plugin of japicmp utilizes the maven framework to lookup the latest SNAPSHOT. Hence, it has no influence on the lookup procedure and it will work like all other maven plugins and take the latest SNAPSHOT either from your local repository or from the remote repository (if it is there newer than in your local one).

    Please implement a release procedure that is conform to the maven proposal and do not use SNAPSHOTS as "releases" as your next build will override it again.

    If for whatever reason you cannot release to your Nexus repository, you may think about installing your releases at least in your local repository according to the maven conventions. This page explains how to install a local jar file as maven artifact with a specific version.