Toby Hammett created MRESOLVER-62:
-------------------------------------

             Summary: Resolver can skip cyclic dependencies underneath removed 
nodes
                 Key: MRESOLVER-62
                 URL: https://issues.apache.org/jira/browse/MRESOLVER-62
             Project: Maven Resolver
          Issue Type: Bug
          Components: resolver
    Affects Versions: Maven Artifact Resolver 1.1.1
            Reporter: Toby Hammett
         Attachments: maven-resolver-cycle-underneath-removed-node.patch

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:
{noformat}
(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
{noformat}
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:
{noformat}
(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
{noformat}
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.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to