Summary
Two API-hygiene problems on DefaultDependencyNode:
-
getChildren() returns the internal mutable list (src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyNode.java:136-138). Callers can add/remove/replace children and corrupt the graph. The builders wrap children in Collections.unmodifiableList when constructing (DefaultDependencyCollectorBuilder.java:233, DefaultDependencyGraphBuilder.java:161), so the mutability is mostly incidental — but the setChildren/getChildren contract leaves the door open, and BuildingDependencyNodeVisitor relies on mutating children of the freshly cloned nodes (so it cannot simply be made immutable everywhere without a builder).
-
The class does not override equals/hashCode. Combined with identity-based comparisons (see the related AncestorOrSelfDependencyNodeFilter issue), value-based matching against rebuilt/cloned trees is impossible.
Suggested fix
Document the mutation contract clearly, or return an unmodifiable view from getChildren(); and add value-based equals/hashCode (e.g. keyed on artifact coordinates) if identity semantics are not intentional.
Summary
Two API-hygiene problems on
DefaultDependencyNode:getChildren()returns the internal mutable list (src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyNode.java:136-138). Callers can add/remove/replace children and corrupt the graph. The builders wrap children inCollections.unmodifiableListwhen constructing (DefaultDependencyCollectorBuilder.java:233,DefaultDependencyGraphBuilder.java:161), so the mutability is mostly incidental — but thesetChildren/getChildrencontract leaves the door open, andBuildingDependencyNodeVisitorrelies on mutating children of the freshly cloned nodes (so it cannot simply be made immutable everywhere without a builder).The class does not override
equals/hashCode. Combined with identity-based comparisons (see the relatedAncestorOrSelfDependencyNodeFilterissue), value-based matching against rebuilt/cloned trees is impossible.Suggested fix
Document the mutation contract clearly, or return an unmodifiable view from
getChildren(); and add value-basedequals/hashCode(e.g. keyed on artifact coordinates) if identity semantics are not intentional.