Is this the correct way to enforce a specific Spring version using the enforcer plugin?
-
22-07-2021 - |
Question
I wish to enforce a specific Spring version (3.1.2) using the maven-enforcer plugin's bannedDependencies rule.
Is this the correct way to configure the enforcer plugin to achieve that ?
<configuration>
<rules>
<bannedDependencies>
<searchTransitive>true</searchTransitive>
<excludes>
<exclude>org.springframework</exclude>
</excludes>
<includes>
<include>org.springframework:*:3.1.2</include>
</includes>
</bannedDependencies>
</rules>
<fail>true</fail>
<failFast>true</failFast>
<ignoreCache>true</ignoreCache>
</configuration>
The above seems to work and doing a mvn enforcer:enforce
on the command line highlighted that v3.1.0 or org.springframework:spring-oxm was being pulled in as a transitive dependency.
It also seems like one might want to use dependencyConvergence rule, but it highlights a lot of dependency errors which are excluded automatically as 'conflicts' by maven.
Here is a snippet with a bit more context :
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>${maven.enforcer.plugin}</version>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
<configuration>
<rules>
<bannedDependencies>
<searchTransitive>true</searchTransitive>
<excludes>
<exclude>org.springframework</exclude>
<exclude>org.springframework.security</exclude>
<exclude>org.slf4j</exclude>
</excludes>
<includes>
<include>org.springframework:*:${spring.version}</include>
<include>org.springframework.security:*:${spring-security.version}</include>
<include>org.slf4j:*:${slf4j.version}</include>
</includes>
</bannedDependencies>
<requireJavaVersion>
<version>${enforce.jdk.version}</version>
</requireJavaVersion>
</rules>
<fail>true</fail>
<failFast>true</failFast>
<ignoreCache>true</ignoreCache>
</configuration>
</plugin>
.....
</plugins>
La solution
The bannedDependencies
snippet in the question above does not work because of the fact that the <include>
tag does not understand the groupId:artifactId:version:type
notation. Thus, wildcard cannot be used to replace whole sections to convey include all versions of ALL artifacts in a group
.
However, by using the maven Dependency Version Range it is possible to enforce a specific dependency.
Given the following versions of a given artifact (in the order that they were released):
3.0.0
, 3.0.1
, 3.1.0
, 3.2.0.RELEASE
, 3.3.0
let's say we want to tell the enforcer plugin to exclude everything but 3.2.0.RELEASE
then the only way to do that is :
exclude versions X where X < DESIRED_VERSION OR X > DESIRED VERSION
The above would effectively mean :
exclude all versions X where X != DESIRED_VERSION
Since the maven dependency version notation does not permit a 'Not Version' notation, we have to make do with using the less than and greater than notations in combination like so:
(,3.2.0.RELEASE),(3.2.0.RELEASE,)
which means: version < '3.2.0.RELEASE' or version > '3.2.0.RELEASE'
.
Finally, a snippet of what works is as follows:
<bannedDependencies>
<searchTransitive>true</searchTransitive>
<excludes>
<exclude>org.springframework:*:(,${spring.version}),(${spring.version},)</exclude>
</excludes>
</bannedDependencies>