Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Know Thy MVN Plugins: Keeping One's Sanity Amidst Open Source Version Hell

DZone's Guide to

Know Thy MVN Plugins: Keeping One's Sanity Amidst Open Source Version Hell

Learn how to keep versions under control with the Versions Maven Plugin and Manven Enforcer Plugin to make software development easier.

· DevOps Zone
Free Resource

The Nexus Suite is uniquely architected for a DevOps native world and creates value early in the development pipeline, provides precise contextual controls at every phase, and accelerates DevOps innovation with automation you can trust. Read how in this ebook.

Problem #1: Everyone knows that keeping up with versions is tough. This is the reason tools such as OpenLogic come to exist. Some companies pay, some companies develop home grown solutions, some live with the version which are getting older every day.

Problem #2: When multiple open source projects once consumed by your product can bring in different versions of the same library. One never knows which will be picked up at run-time and behavior on the developer’s box based on the Murphy’s Law will be different from the server run-time.

This does not have to be such an ordeal. With the power of maven plugins this can be solved relatively easy. Versions Maven Plugin and Maven Enforcer Plugin to the rescue!

Versions Maven Plugin will keep versions up-to-date and as you probably guessed from the name Maven Enforcer plugin will be guarding against multiple versions of the maven artifact in the build package produced.

Let’s see how one introduced enforcer into the mix first. The code below can go in the parent pom.xml of the project, or global parent of the projects if one exists.

<project …>
…
<plugins>
…
<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-enforcer-plugin</artifactId>
        <version>1.4</version>
        <executions>
          <execution>
            <id>enforce-versions</id>
            <goals>
              <goal>enforce</goal>
            </goals>
            <configuration>
              <rules>
                <requireMavenVersion>
                  <version>[2.2.*,)</version>
                </requireMavenVersion>
                <requireJavaVersion>
                  <version>[1.7.*,)</version>
                </requireJavaVersion>
                <DependencyConvergence/>
              </rules>
            </configuration>
          </execution>
        </executions>
      </plugin>
…
</plugins>
…
</project>

For each dependency version collision one has to pick the version to keep and exclude the ones that are mismatched. See maven help page for details. If one wants absolute guarantee of the version used, this is the only way to go. An example of excluded dependencies will be:

<project …>
…
<dependencies>
…
<dependency>
<groupId>com.lordofthejars</groupId>
<artifactId>nosqlunit-mongodb</artifactId>
<version>${nosqlunit.veresion}</version>
  <scope>test</scope>
  <exclusions>
      <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      </exclusion>
      <exclusion>
      <groupId>com.github.fakemongo</groupId>
      <artifactId>fongo</artifactId>
      </exclusion>
      <exclusion>
      <groupId>org.mongodb</groupId>
      <artifactId>mongo-java-driver</artifactId>
      </exclusion>
  </exclusions>
</dependency>
…
</dependencies>
…
</project>

From the open source developer side, producing two flavors of the package for consumption with and without dependencies can make world a better place. This is the difference of maven scope 'provided' vs. default scope 'compile'. Apache Maven Shade Plugin can be used to produce the version with the dependencies to be used there no conflicts can arise along with the version that is artifact version independent and can be used without version conflicts.

Once all conflicts are resolved and one version of each artifact is in the final build product guaranteed, one should check if ones project is up to date. It is a good practice to do the check at the beginning of the new version.

To check for outdates dependencies, and plugins, and bring those up to date in the controlled manner (manually) one can execute:

As an alternative one can let the plugin update the versions by executing following

This last mvn command I am going to share is a bonus for the dedicated reader. It allows changing versions across the project and its modules painlessly:

  • mvn versions:set -DgenerateBackupPoms=false -DnewVersion=<version>

The DevOps Zone is brought to you in partnership with Sonatype Nexus.  See how the Nexus platform infuses precise open source component intelligence into the DevOps pipeline early, everywhere, and at scale. Read how in this ebook

Topics:
devops ,maven ,plugins ,openlogic ,mvn

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}