Utilizing Maven Enforcer plugin to ensure dependency and version usage

Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project’s build, reporting and documentation from a central piece of information.  Using Maven for managing builds, reporting, and documentation has become a standard practice in Java development. The Enforcer plugin is an under utilized plugin that helps maintain project standards.  It provides goals to control certain environmental constraints such as Maven version, JDK version and OS family along with many more standard rules and user created rules.

By Ryan Van Fleet

What can the Enforcer plugin do for your project?

  • Enforce banned dependencies:
  • Developers may add dependencies to a pom that have been deemed by your organization to be undesirable. These dependencies can be banned and reported during the build.
  • Some third party dependencies include transitive dependencies that may conflict with your project’s dependencies. For example:

If your project uses Logback and SFL4j, it is a best practice to ensure no other logging frameworks are included in the build. However, the Spring Framework transitively includes commons-logging.

Older versions of dependencies may break the build. This often occurs when a third party dependency has a transitive dependency, which is an older version of a dependency your project explicitly includes. Depending on the order of the dependencies in the pom, and your class loader, the older dependency maybe loaded before the newer causing runtime and build issues.

  • Reduce package size when packaging the application in a war or jar, ensuring banned dependencies are excluded will reduce the size of super-jars and war files.
  • Enforce development environments:
  • Ensure the development team develops, tests, and builds with a specific version of Java, OS, and Maven.

Usage

Consider the following example:

<project>
[…]
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-enforcer-plugin</artifactId>
                <version>1.4.1</version>
                <executions>
                    <execution>
                        <id>enforce-banned-dependencies</id>
                        <goals>
                            <goal>enforce</goal>
                        </goals>
                        <configuration>
                            <rules>
                                <bannedDependencies>
                                    <searchTransitive>true</searchTransitive>
                                    <excludes>
                                        <exclude>commons-logging:commons-logging</exclude>
                                        <exclude>log4j:log4j</exclude>
                                        <exclude>org.apache.httpcomponents:httpclient:(4.3]</exclude>
                                        <exclude>org.mockito:mockito-all</exclude>
                                    </excludes>
                                    <includes>
                                        <include>org.mockito:mockito-all:*:*:test</include>
                                    </includes>
                                    <message>A banned dependency or plugin was found!</message>
                                </bannedDependencies>
                                <requireMavenVersion>
                                    <version>[3.3,)</version>
                                </requireMavenVersion>
                                <requireJavaVersion>
                                    <version>1.8</version>
                                </requireJavaVersion>
                                <requireOS>
                                    <family>unix</family>
                                </requireOS>
                            </rules>
                            <fail>true</fail>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
[…]
        </plugins>
    </build>
[…]
</project>

Banning Dependencies

Banning dependencies follow the pattern of:

groupId[:artifactId][:version][:type][:scope][:classifier]

where everything after the groupId is optional[1].  The banned dependencies also follow the normal Maven pattern matching:

  • * – all
  • [4.3,4.4] – matches the exact version within the brackets
  • (4.3] – matches all previous versions up to and including 4.3
  • [4.3,) – matches all version 4.3 and above

In the example above, we have banned the following dependencies:

  • All versions of commons-logging
  • All versions of log4j
  • Any version less than or equal to 4.3 of httpclient
  • All versions of Mockito unless it is in the test scope

Enforcing the Environment

The Enforcer allows the ability to enforce the development environment. The standard Maven pattern matching, discussed above, applies to each of these.

  • < requireMavenVersion/> : enforces the Maven version
  • < requireJavaVersion /> : enforces the Java version
  • < requireOS /> : enforces the OS.

In the above example, we are enforcing the following:

  • Maven version 3.3 and above.
  • Java version 1.8 and above
  • All Unix OS

Transitive Search

The searchTransitive node enables or disables enforcement for included third party dependencies. For example, if this tag is true, it allows Enforcer to ensure Spring doesn’t include commons-logging.  The default value is true.  Note: You will need to explicitly exclude the dependency as in the following  example:

<dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-core</artifactId>
         <version>4.2.1.RELEASE version>
         <exclusions>
            <exclusion>
               <groupId>commons-logging</groupId>
               <artifactId>commons-logging</artifactId>
            </exclusion>
         </exclusions>
</dependency>

Conclusion

Although the Maven Enforcer plugin is not a required part of Maven, its diligent use can improve your project. Its benefits include enforcing project policies, increased application performance, and preempting runtime issues.

Resources

[1] Line is taken directly from the Maven Enforcer Plugin homepage. See References.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s