Skip to content

vandmo/dependency-lock-maven-plugin

Repository files navigation

dependency-lock-maven-plugin

Build Status usefulness 100% Maven Central Apache License, Version 2.0, January 2004

Maven only requires you to specify versions of dependencies that you use directly. Transitive dependencies aren't visible in the pom.xml and their version is chosen in a seemingly random way.

This Maven plugin enables you to:

  • Review exactly which dependencies you have, including transitive ones
  • Make sure dependencies are not accidentally changed
  • Verify the integrity of your dependencies to avoid supply chain attacks, see Dependency Confusion
  • Track changes to dependencies in your SCM
  • Enable vulnerability scanning in all your dependencies, including transitive ones
  • Enable Dependabot Security Alerts for transitive dependencies

It is a bit like mvn dependency:list but the output is intended to be tracked by you SCM and the check goal makes sure you don't forget to update the file.

Locking

mvn se.vandmo:dependency-lock-maven-plugin:lock will create a file named dependencies-lock.json by default.

You should then commit that file to your source control of choice.

Choose between JSON format and POM XML format. The latter is more verbose but will be detected by Dependabot Security Alerts.

Validating

The following snippet in your pom.xml file will make sure that the actual dependencies are the same as in the dependencies-lock.json file.

<build>
  <plugins>
    <plugin>
      <groupId>se.vandmo</groupId>
      <artifactId>dependency-lock-maven-plugin</artifactId>
      <version>1.0</version>
      <executions>
        <execution>
          <id>check</id>
          <phase>validate</phase>
          <goals>
            <goal>check</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Tips

Adding the following in ~/.m2/settings.xml will allow you to write mvn dependency-lock:lock

<pluginGroups>
  <pluginGroup>se.vandmo</pluginGroup>
</pluginGroups>

Shared Configuration

Configuration shared between all goals.

filename

The filename of the lock file.

format

Which lock file format to use, defaults to json.

  • json, lock file in JSON format, default filename is dependency-lock.json
  • pom, lock file in POM XML format, default filename is .dependeny-lock/pom.xml

Goals

check

Checks that actual dependencies matches the lock file. Fails the build if there is no match. Expects a lock file to exist.

If some dependencies are part of the same multi-module project you might want those dependencies to be the same version as the artifact where the dependencies are locked. You can achieve this by configuring the plugin like such:

<configuration>
  <dependencySets>
    <dependencySet>
      <includes>
        <include>org.myorg:myapplication-*</include>
      </includes>
      <version>use-project-version</version>
    </dependencySet>
  </dependencySets>
</configuration>

The filter syntax is [groupId]:[artifactId]:[type]:[version] where each pattern segment is optional and supports full and partial * wildcards. An empty pattern segment is treated as an implicit wildcard. For example, org.myorg.* will match all artifacts whose group id starts with org.myorg., and :::*-SNAPSHOT will match all snapshot artifacts.

dependencySets

dependencySets are ordered in reverse priority which means that a dependencySet at the end of the list will override any previously set configuration for the matching dependencies. A dependencySet is configured as follows:

Field Description
includes Patterns describing dependencies that should be included
excludes Patterns describing dependencies that should be excluded
allowExtraneous Whether extraneous dependencies should be allowed or not
allowMissing Whether missing dependencies should be allowed or not
version "check", "ignore", "use-project-version" or "snapshot"
integrity "check" or "ignore"

"snapshot" version matching means that 1.2.3-SNAPSHOT will match something like 1.2.3-20221104.072032-1 and similar.

lock

Creates a lock file from the actual dependencies.

Ignored fields can be actually marked as ignored in the lock file with markIgnoredAsIgnored configuration property.

<configuration>
    <markIgnoredAsIgnored>true</markIgnoredAsIgnored>
    <dependencySets>
        <dependencySet>
            <includes>
                <include>com.company:our-subproject-*</include>
            </includes>
            <version>ignore</version>
            <integrity>ignore</integrity>
        </dependencySet>
    </dependencySets>
</configuration>

Notes

Dependabot Updates won't work

Dependabot Updates currently creates a single PR for each change. If you use pom format and merge all PRs from Dependabot then that combined build might work, but each single PR will fail. There are feature requests for combined PRs for Dependabot which, if implemented, could make a combined PR work. Another approach to automate the creation of PRs would be to have a GitHub workflow that creates a combined PR based on the Dependabot PRs.

News in version 1.x

  • Integrity checking is enabled by default
  • Configuration is more verbose but also more flexible