Using with Apache Maven
Most projects use Range Resolver through rangeresolver-maven-plugin. The plugin reads pom.deps, resolves it,
writes the chosen versions back into your POMs, and publishes the script so other projects can import it.
Add the plugin
Section titled “Add the plugin”Add the plugin to the top-level pom.xml. Two goals belong in the normal build:
resolve-propertiesmakes the locked versions available as properties.attach-depspublishespom.depsalongside the project’s other artifacts.
<build> <plugins> <plugin> <groupId>io.repaint</groupId> <artifactId>rangeresolver-maven-plugin</artifactId> <version><!-- latest release --></version> <executions> <execution> <id>resolve-properties</id> <phase>initialize</phase> <goals> <goal>resolve-properties</goal> </goals> </execution> <execution> <id>attach-deps</id> <phase>verify</phase> <goals> <goal>attach-deps</goal> </goals> </execution> </executions> </plugin> </plugins></build>The other goals change files, so you run them by hand when you want to update dependencies.
Where pom.deps lives
Section titled “Where pom.deps lives”The plugin looks for the script next to the top-level POM of the build, with that POM’s extension replaced by
deps. For a normal multi-module build, that is pom.deps beside the root pom.xml. One script covers the whole
reactor.
If the file is missing, every goal logs a warning and does nothing.
Running the goals
Section titled “Running the goals”io.repaint isn’t one of Maven’s default plugin groups, so either use the full coordinates:
mvn io.repaint:rangeresolver-maven-plugin:resolve-depsor add the group to ~/.m2/settings.xml once and use the short rangeresolver: prefix:
<pluginGroups> <pluginGroup>io.repaint</pluginGroup></pluginGroups>mvn rangeresolver:resolve-depsThe examples below use the short form.
The update cycle
Section titled “The update cycle”mvn rangeresolver:resolve-deps # resolve pom.deps and rewrite the POMsgit diff # review what movedmvn verify # build and test with the new versionsmvn rangeresolver:lock-deps # accept them: resolved → lockedAdd -U to resolve-deps to check remote repositories for new versions now, rather than once a day.
To pick up newer releases of artifacts that come from an import, name them for one run without editing the script:
mvn rangeresolver:resolve-deps -DallowUnlocked='^com\.example:.*$'| Goal | Default phase | What it does |
|---|---|---|
resolve-deps |
initialize |
Resolves pom.deps, writes the results back to it, and rewrites the project files (details). |
lock-deps |
initialize |
Moves every resolved record to locked. |
unlock-deps |
initialize |
Moves every locked record back to resolved. The next resolve-deps then no longer treats those versions as a minimum. |
update-lower-bounds |
initialize |
Raises the lower bound of each resolve range to the newest version currently available in it. |
resolve-properties |
initialize |
Sets a property for every resolved, locked and deprecated record in every module of the build (details). |
attach-deps |
verify |
Attaches pom.deps to the build as classifier bill-of-materials, type deps, so it is installed and deployed with the project. |
verify |
initialize |
Fails if the project declares a dependency that pom.deps doesn’t cover (details). |
All goals except verify and resolve-properties run only once, at the root of the build.
What resolve-deps rewrites
Section titled “What resolve-deps rewrites”After resolving, resolve-deps updates the version of every artifact with a resolved, locked, deprecated or
blacklisted record wherever it appears in these files:
pom.xmlandtile.xmlfiles, up to 10 directories below the root: dependencies, dependency management, plugins, plugin management, plugin dependencies,maven-compiler-pluginannotation processor paths, the parent version, properties named after a record’s property, and the same sections inside profiles.- Tiles in a
tiles-maven-pluginconfiguration, written asgroup:artifact:[version]. .mvn/extensions.xmlbuild extensions.Dockerfile*FROMlines, which are pinned to the image digest fromresolve docker.
Artifacts built by the current reactor are never rewritten. Before changing a file, the plugin saves the original as
<name>.orig.
Dependency versions
Section titled “Dependency versions”Dependency versions are written as exact ranges, such as [2.0.17], so Maven can’t substitute a different version
during conflict resolution. To write plain versions instead:
relaxedScopes: a regex of dependency scopes, for exampletest|provided.relaxedGavs: a regex ofgroup:artifactkeys.
Exclusions
Section titled “Exclusions”When a compile, runtime or provided dependency has no <exclusions>, the plugin adds a wildcard exclusion:
<exclusions> <exclusion> <groupId>*</groupId> <artifactId>*</artifactId> </exclusion></exclusions>This makes every transitive dependency explicit: anything the project needs must be declared, and so resolved. The
plugin leaves a dependency that already has <exclusions> unchanged.
For test-scoped dependencies, testExclusions lists group:artifact patterns (* wildcards allowed). Each
dependency matching one of them has every listed pattern added as an exclusion.
Pruning unused records
Section titled “Pruning unused records”With filterUnusedDependencies set, resolve-deps drops records for artifacts the build doesn’t reference
anywhere. Keep specific artifacts with retainUnusedDependencies. That is useful when the script you
import locks far more than this project uses.
Properties
Section titled “Properties”resolve-properties sets one property per record, in every module of the build:
- each
resolved,lockedanddeprecatedrecord, under<artifactId>.versionor its alias; - each module in the reactor, under
<artifactId>.version, set to the module’s own version.
The properties are set in the initialize phase, so later plugins and resource filtering can use them:
guava=${guava.version}By then, Maven has already built the project model, so these properties don’t reach <parent>, <dependencies>,
or <plugins> versions. Write those versions literally, or declare a POM property with the same name. Either way,
resolve-deps keeps them up to date:
<properties> <guava.version>33.8.0-jre</guava.version> <!-- updated by resolve-deps --></properties>
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>${guava.version}</version></dependency>Verify
Section titled “Verify”verify compares each module’s dependencies and dependency management with the resolved and locked records.
For every undeclared dependency it logs an error and prints a line you can paste into pom.deps:
[WARNING] Add the following script to the file /work/project/pom.deps:
resolve highest org.slf4j:slf4j-api:[2.0.17,3.0.0);The suggested range runs from the declared version up to the next major version.
Set strictDependency to false to log these errors without failing the build.
Deprecated and blacklisted artifacts
Section titled “Deprecated and blacklisted artifacts”| Parameter | Default | When false |
|---|---|---|
allowDeprecatedDependencies |
true |
resolve-deps and resolve-properties fail if a deprecated record applies to the build. |
allowBlacklistedDependencies |
true |
resolve-deps fails if a blacklisted record applies to the build. |
Both are user properties, so you can set them in <properties> or on the command line:
-DallowDeprecatedDependencies=false.
Releases
Section titled “Releases”With commitChanges set, the goals that edit files commit their changes through the project’s <scm> connection,
and pushChanges also pushes them. Commits happen only during a release, that is, when a release.properties
file is present, as it is while maven-release-plugin runs. This lets a release lock the versions it was built with.
Parameter reference
Section titled “Parameter reference”| Parameter | User property | Default | Goals |
|---|---|---|---|
allowUnlocked |
allowUnlocked |
none | all |
allowSnapshots |
allowSnapshots |
none | all |
allowDeprecatedDependencies |
allowDeprecatedDependencies |
true |
resolve-deps, resolve-properties |
allowBlacklistedDependencies |
allowBlacklistedDependencies |
true |
resolve-deps |
filterUnusedDependencies |
filterUnusedDependencies |
false |
resolve-deps |
retainUnusedDependencies |
none | none | resolve-deps |
relaxedScopes |
relaxedScopes |
none | resolve-deps |
relaxedGavs |
relaxedGavs |
none | resolve-deps |
testExclusions |
testExclusions |
none | resolve-deps |
prettyPrintPomFormat |
prettyPrintPomFormat |
false |
resolve-deps |
strictDependency |
strictDependency |
true |
verify |
commitChanges |
none | false |
goals that edit files |
pushChanges |
none | false |
goals that edit files |
allowUnlocked and allowSnapshots act like extra allow statements for
one run.