Jenkins : How to fix RequireUpperBoundDeps

Deprecated.

You should refer Understanding requireUpperBoundDeps failures and fixes in jenkins.io instead.

The issue

  • You may see a error like followings when building a plugin:

    $ mvn validate
    [INFO] Scanning for projects...
    ...
    [INFO] --- maven-enforcer-plugin:3.0.0-M2:enforce (display-info) @ groovy-postbuild ---
    [INFO] Adding ignore: module-info
    [WARNING] Rule 4: org.apache.maven.plugins.enforcer.RequireUpperBoundDeps failed with message:
    Failed while enforcing RequireUpperBoundDeps. The error(s) are [
    Require upper bound dependencies error for org.jenkins-ci.plugins.workflow:workflow-api:2.27 paths to dependency are:
    +-org.jvnet.hudson.plugins:groovy-postbuild:2.5-SNAPSHOT
      +-org.jenkins-ci.plugins.workflow:workflow-cps:2.54
        +-org.jenkins-ci.plugins.workflow:workflow-api:2.27
    and
    +-org.jvnet.hudson.plugins:groovy-postbuild:2.5-SNAPSHOT
      +-org.jenkins-ci.plugins.workflow:workflow-job:2.32
        +-org.jenkins-ci.plugins.workflow:workflow-api:2.32
    and
    +-org.jvnet.hudson.plugins:groovy-postbuild:2.5-SNAPSHOT
      +-org.jenkins-ci.plugins.workflow:workflow-basic-steps:2.4
        +-org.jenkins-ci.plugins.workflow:workflow-api:2.8
    and
    +-org.jvnet.hudson.plugins:groovy-postbuild:2.5-SNAPSHOT
      +-org.jenkins-ci.plugins.workflow:workflow-cps:2.54
        +-org.jenkins-ci.plugins.workflow:workflow-support:2.17
          +-org.jenkins-ci.plugins.workflow:workflow-api:2.25
    ]
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD FAILURE
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  8.279 s
    [INFO] Finished at: 2019-06-16T02:34:04Z
    [INFO] ------------------------------------------------------------------------
    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-enforcer-plugin:3.0.0-M2:enforce (display-info) on project groovy-postbuild: Some Enforcer rules have failed. Look above for specific messages explaining why the rule failed. -> [Help 1]
    [ERROR]
    [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
    [ERROR] Re-run Maven using the -X switch to enable full debug logging.
    [ERROR]
    [ERROR] For more information about the errors and possible solutions, please read the following articles:
    [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
  • This page explains why this error happens and how to fix that.
    • You'd better to read linked pages for details. This page is a hub for those pages.

What is require upper bound dependencies error?

  • Maven determines the artifact versions with "nearest definition" rule.
    • http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
      Maven picks the "nearest definition". That is, it uses the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, the first declaration wins.
    • Example 1: Shallowest one wins.

      Your project dependencies
        +-A
          +-B
            +-C
              +-D-2.0
        +-E
          +-D-1.0    <- This version is used for artifact D as this is "nearest".


      • Especially, the explicit definition always wins.

        Your project dependencies
          +-A
            +-B-2.0
          +-B-1.0 <- This version is used for artifact B as this is "nearest".
        
        
    • Example 2: The first one wins for same depths.

      Your project dependencies
        +-A
          +-B-1.0 <- This version is used for artifact B as this is "nearest".
        +-C
          +-B-2.0
  • "nearest definition" may result the project use artifacts with unexpected versions and runtime errors.
    • E.g. artifact A expects artifact B-2.0. But "nearest definition" resolves B to B-1.0 and A fails to call a feature added since B-2.0
  • maven-enforcer-plugin detects those inconsistencies and treat them as errors.

How can I test require upper bound dependencies error

mvn validate


How to fix require upper bound dependencies error

  • If that artifact is already declared in pom.xml, update the version in the pom.xml to the newest version listed in the output from maven-enforcer-plugin.
    • pom.xml:

          <dependencies>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>A</artifactId>
              <version>1.0</version>
            </dependency>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>B</artifactId>
              <version>1.0</version>
            </dependency>
          </dependencies>
    • outputs from maven-enforcer-plugin:

      Require upper bound dependencies error for org.org.jenkins-ci.plugins:A:1.0 paths to dependency are:
      +-org.jenkins-ci.plugins:your-plugin:1.0-SNAPSHOT
        +-org.jenkins-ci.plugins:A:1.0
      and
      +-org.jenkins-ci.plugins:your-plugin:1.0-SNAPSHOT
        +-org.jenkins-ci.plugins:B:1.0
          +-org.jenkins-ci.plugins:A:2.0


      • A-2.0 is the newest one!
    • Updated pom.xml:

      <dependencies>
        <dependency>
          <groupId>org.jenkins-ci.plugins</groupId>
          <artifactId>A</artifactId>
          <version>2.0</version>  <!-- <- update here! -->
        </dependency>
        <dependency>
          <groupId>org.jenkins-ci.plugins</groupId>
          <artifactId>B</artifactId>
          <version>1.0</version>
        </dependency>
      </dependencies>
  • If that artifact isn't declared in pom.xml, there're several ways. Using <dependencyManagement> (the first way) is recommended as it's easiest to do and it gets clear that what dependency is required directly by your plugin and what is to resolve RequireUpperBoundDeps.
    • A (recommended): Update pom.xml and declare the version in <dependencyManagement> to use the newest version listed in the output from maven-enforcer-plugin.
      • pom.xml:

        <dependencies>
          <dependency>
            <groupId>org.jenkins-ci.plugins</groupId>
            <artifactId>A</artifactId>
            <version>1.0</version>
          </dependency>
          <dependency>
            <groupId>org.jenkins-ci.plugins</groupId>
            <artifactId>B</artifactId>
            <version>1.0</version>
          </dependency>
        </dependencies>
        
        
      • outputs from maven-enforcer-plugin:

        Require upper bound dependencies error for org.org.jenkins-ci.plugins:C:1.0 paths to dependency are:
        +-org.jenkins-ci.plugins:your-plugin:1.0-SNAPSHOT
          +-org.jenkins-ci.plugins:A:1.0
            +-org.jenkins-ci.plugins:C:1.0
        and
        +-org.jenkins-ci.plugins:your-plugin:1.0-SNAPSHOT
          +-org.jenkins-ci.plugins:B:1.0
            +-org.jenkins-ci.plugins:C:2.0


        • C-2.0 is the newest one!
      • Updated pom.xml:

        <dependencies>
          <dependency>
            <groupId>org.jenkins-ci.plugins</groupId>
            <artifactId>A</artifactId>
            <version>1.0</version>
          </dependency>
          <dependency>
            <groupId>org.jenkins-ci.plugins</groupId>
            <artifactId>B</artifactId>
            <version>1.0</version>
          </dependency>
        </dependencies>
        <dependencyManagement>
          <dependencies>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>C</artifactId>
              <version>2.0</version>
            </dependency>
          </dependencies>
        </dependencyManagement>
      • Maven-enforcer-plugin detects an error if the version in <dependencyManagement> is older than the actual required version (So you don't need to worry that this declation cause another issue in future dependency updates.):

        Require upper bound dependencies error for org.jenkins-ci.plugins:C:2.0 paths to dependency are:
        +-org.jenkins-ci.plugins:your-plugin:1.0-SNAPSHOT
          +-org.jenkins-ci.plugins:A:1.0
            +-org.jenkins-ci.plugins:C:2.0 (managed) <-- org.jenkins-ci.plugins:C:1.0
        and
        +-org.jenkins-ci.plugins:your-plugin:1.0-SNAPSHOT
          +-org.jenkins-ci.plugins:B:2.0
            +-org.jenkins-ci.plugins:C:2.0 (managed) <-- org.jenkins-ci.plugins:C:3.0
    • Other ways (collapsed as not so recommended as <dependencyManagement>):

      Click here to expand...
      • B: Add explicit dependency to the artifact.
        • pom.xml:

          <dependencies>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>A</artifactId>
              <version>1.0</version>
            </dependency>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>B</artifactId>
              <version>1.0</version>
            </dependency>
          </dependencies>
          
          
        • outputs from maven-enforcer-plugin:

          Require upper bound dependencies error for org.org.jenkins-ci.plugins:C:1.0 paths to dependency are:
          +-org.jenkins-ci.plugins:your-plugin:1.0-SNAPSHOT
            +-org.jenkins-ci.plugins:A:1.0
              +-org.jenkins-ci.plugins:C:1.0
          and
          +-org.jenkins-ci.plugins:your-plugin:1.0-SNAPSHOT
            +-org.jenkins-ci.plugins:B:1.0
              +-org.jenkins-ci.plugins:C:2.0


          • C-2.0 is the newest one!
        • Updated pom.xml:

          <dependencies>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>A</artifactId>
              <version>1.0</version>
            </dependency>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>B</artifactId>
              <version>1.0</version>
            </dependency>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>C</artifactId>
              <version>2.0</version>
            </dependency>
          </dependencies>
          
      • C: declare <exclusions>

        • pom.xml:

          <dependencies>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>A</artifactId>
              <version>1.0</version>
            </dependency>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>B</artifactId>
              <version>1.0</version>
            </dependency>
          </dependencies>
          
          
        • outputs from maven-enforcer-plugin:

          Require upper bound dependencies error for org.org.jenkins-ci.plugins:C:1.0 paths to dependency are:
          +-org.jenkins-ci.plugins:your-plugin:1.0-SNAPSHOT
            +-org.jenkins-ci.plugins:A:1.0
              +-org.jenkins-ci.plugins:C:1.0
          and
          +-org.jenkins-ci.plugins:your-plugin:1.0-SNAPSHOT
            +-org.jenkins-ci.plugins:B:1.0
              +-org.jenkins-ci.plugins:C:2.0


          • C-1.0 depended from A-1.0 is old.

        • Updated pom.xml:

          <dependencies>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>A</artifactId>
              <version>1.0</version>
              <exclusions>
                <exclusion>
                  <groupId>org.jenkins-ci.plugins</groupId>
                  <artifactId>C</artifactId>
                </exclusion>
              </exclusions>
            </dependency>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>B</artifactId>
              <version>1.0</version>
            </dependency>
          </dependencies>
          
      • D: reordering dependencies may resolve the issue
        • pom.xml:

          <dependencies>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>A</artifactId>
              <version>1.0</version>
            </dependency>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>B</artifactId>
              <version>1.0</version>
            </dependency>
          </dependencies>
          
        • outputs from maven-enforcer-plugin:

          Require upper bound dependencies error for org.org.jenkins-ci.plugins:C:1.0 paths to dependency are:
          +-org.jenkins-ci.plugins:your-plugin:1.0-SNAPSHOT
            +-org.jenkins-ci.plugins:A:1.0
              +-org.jenkins-ci.plugins:C:1.0
          and
          +-org.jenkins-ci.plugins:your-plugin:1.0-SNAPSHOT
            +-org.jenkins-ci.plugins:B:1.0
              +-org.jenkins-ci.plugins:C:2.0


          • C-1.0 is picked as it's "nearest".

        • Updated pom.xml:

          <dependencies>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>B</artifactId>
              <version>1.0</version>
            </dependency>
            <dependency>
              <groupId>org.jenkins-ci.plugins</groupId>
              <artifactId>A</artifactId>
              <version>1.0</version>
            </dependency>
          </dependencies>
          

See also