Details
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.