Uploaded image for project: 'Maven Resolver'
  1. Maven Resolver
  2. MRESOLVER-62

Resolver can skip cyclic dependencies underneath removed nodes

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Reopened
    • Critical
    • Resolution: Unresolved
    • Maven Artifact Resolver 1.1.1
    • None
    • Resolver

    Description

      While updating dependencies in one of my company's Maven projects, I got a StackOverflowError involving infinite recursion at org.apache.maven.RepositoryUtils#toArtifacts. After some investigation, I believe I have traced the issue to a bug in ConflictResolver which can occur when encountering multiple dependency cycles. Specifically, I think the criteria for failure are:

      • One cycle appears nearer to the root than the other cycle as a child of a node that will be removed.
      • That cycle is also a child of the other cycle elsewhere in the dependency graph.

      For example, here is a dependency graph analogous to the one I was working with when I encountered the StackOverflowError:

      (null)
      +- gid:a:1
      |  \- gid:x:1                  (x)
      |     \- gid:y:1
      |        \- ^x
      +- gid:a:2
      +- gid:b:1
      |  +- gid:c:1
      |     \- gid:d:1               (d)
      |        \- ^x
      \- gid:m:1
         \- gid:n:1
            +- gid:p:1
            |  \- gid:q:1
            \- gid:q:2
               \- gid:p:2
                  \- ^d
      

      This graph has a cycle (x and y) underneath a node that is removed from the tree (a:1). This cycle also appears as a child of another cycle. Specifically, q and p depends on d, which depends on x.
      After conflicts are resolved in this graph, the node for gid:y:1 still has a reference to gid:x:1, although I believe it should have been removed. This cycle in the graph led to the StackOverflowError I observed.

      Another example, derived from the first, shows a slightly different problem:

      (null)
      +- gid:a:1
      |  \- gid:x:1                  (x)
      |     \- gid:y:1
      |        \- ^x
      +- gid:a:2
      \- gid:m:1
         \- gid:n:1
            +- gid:p:1
            |  \- gid:q:1
            \- gid:q:2
               |- gid:p:2
               \- ^x
      

      In this case, as with the first, there is a cycle underneath a node that will be removed. That cycle (x and y) is also a dependency of node gid:q:2, which is itself a member of a cycle with p. When conflicts are resolved in this case, the resulting graph does not contain gid:x:1 at all!

       

      A potential workaround for this issue is to declare a direct dependency on one of the artifacts in the cycle that is not handled correctly.

       

      I have attached a patch for maven-resolver-util which adds both of the preceding examples as unit tests.  Please let me know if there's any other information I can provide.

      Attachments

        Activity

          People

            Unassigned Unassigned
            thammett Toby Hammett
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated: