Karl Richter Karl Richter - 13 days ago 8
Java Question

Why does maven-enforcer-plugin detect maven 3.2.5 when it's run with 3.1.1 on travis-ci.org?

I have a project document-scanner-aggregator which runs fine locally when run with Maven 3.1.1, i.e.

~/apache-maven-3.1.1/bin/mvn clean install
, but doesn't on travis-ci.org where it detects Maven 3.2.5 which suspiciously is the version provided by travis-ci.org. However it's not supposed to do that, because the Maven version which runs the build is supposed to be enforced, right?

The failure is

[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireMavenVersion failed with message:
Detected Maven Version: 3.2.5 is not in the allowed range (,3.2).
...
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-enforcer-plugin:1.4:enforce (enforce-versions) on project javaocr-parent: Some Enforcer rules have failed. Look above for specific messages explaining why the rule failed. -> [Help 1]


and the configuration is

<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>
<!--different rules for different issues-->
<!--3.3.x causes `java.lang.NoClassDefFoundError: org/eclipse/aether/spi/connector/Transfer$State` which is caused by certain maven versions, see https://cwiki.apache.org/confluence/display/MAVEN/AetherClassNotFound for details-->
<version>(,3.3)</version>
<!--3.2.x causes `No implementation for org.eclipse.aether.connector.wagon.WagonConfigurator was bound.`-->
<version>(,3.2)</version>
</requireMavenVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>


in javaocr.

The
.travis.yml
is

language: java
install:
- wget http://mirrors.ae-online.de/apache/maven/maven-3/3.1.1/binaries/apache-maven-3.1.1-bin.tar.gz && tar xf apache-maven-3.1.1-bin.tar.gz
- apache-maven-3.1.1/bin/mvn clean install

Answer

You're misunderstanding the role of the Enforcer Plugin:

The Enforcer plugin 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.

Its goal is not to do magic so that the configured rules are verified, but it is to fail the build when one of the rules is not verified. Put another way, it checks the list of configured rules, so that the build cannot continue if one of those isn't verified. The reason is that if one of the pre-requisite for the build is not met, it is better to fail as early as possible.

In your case, the requireMavenVersion rule enforces that the build is done with a Maven version strictly lower than 3.2. It will not spawn a new Maven instance if you're running the build with a Maven 3.2.5 so that the rule is verified; which version should it use, and where would it get it? Instead, it detects that the build is done with a Maven version that is disallowed, and fails accordingly. Since the Travis build is configured to use Maven 3.2.5, it is expected to fail, and you need to install a Maven version lower than 3.2 for your Travis build.

To use a different Maven version, like 3.1.1, on Travis CI, you can have the following in .travis.yml:

before_install:
  - wget http://mirrors.ae-online.de/apache/maven/maven-3/3.1.1/binaries/apache-maven-3.1.1-bin.tar.gz
  - tar xf apache-maven-3.1.1-bin.tar.gz
  - export M2_HOME=$PWD/apache-maven-3.1.1
  - export PATH=$M2_HOME/bin:$PATH 

install: /bin/true

script: mvn clean install

As a side-note, your current configuration of

<requireMavenVersion>
    <version>(,3.3)</version>
    <version>(,3.2)</version>
</requireMavenVersion>

is completely equivalent to

<requireMavenVersion>
    <version>(,3.2)</version>
</requireMavenVersion>

The range (,3.2) means that it matches version strictly lower than 3.2. Therefore, requiring that it is also strictly lower than 3.3 is redundant (since 3.2 is before 3.3).