Class ConflictResolver
java.lang.Object
org.eclipse.aether.util.graph.transformer.ConflictResolver
- All Implemented Interfaces:
DependencyGraphTransformer
- Direct Known Subclasses:
ClassicConflictResolver
,PathConflictResolver
Abstract base class for dependency graph transformers that resolve version and scope conflicts among dependencies.
For a given set of conflicting nodes, one node will be chosen as the winner. How losing nodes are handled depends
on the configured verbosity level: they may be removed entirely, have their children removed, or be left in place
with conflict information. The exact rules by which a winning node and its effective scope are determined are
controlled by user-supplied implementations of
ConflictResolver.VersionSelector
, ConflictResolver.ScopeSelector
,
ConflictResolver.OptionalitySelector
and ConflictResolver.ScopeDeriver
.
Available Implementations:
PathConflictResolver
- Recommended high-performance implementation with O(N) complexityClassicConflictResolver
- Legacy implementation for backward compatibility (O(N²) worst-case)
Implementation Selection Guide:
- New Projects: Use
PathConflictResolver
for optimal performance - Large Multi-Module Projects: Use
PathConflictResolver
to avoid performance bottlenecks - Maven 4+ Environments: Use
PathConflictResolver
for best build performance - Legacy Compatibility: Use
ClassicConflictResolver
only when exact Maven 3.x behavior is required
Usage Example:
// Recommended: High-performance path-based resolver
DependencyGraphTransformer transformer = new ChainedDependencyGraphTransformer(
new PathConflictResolver(
new NearestVersionSelector(),
new JavaScopeSelector(),
new SimpleOptionalitySelector(),
new JavaScopeDeriver()),
// other transformers...
);
// Legacy: Classic resolver for backward compatibility
DependencyGraphTransformer legacyTransformer = new ChainedDependencyGraphTransformer(
new ClassicConflictResolver(
new NearestVersionSelector(),
new JavaScopeSelector(),
new SimpleOptionalitySelector(),
new JavaScopeDeriver()),
// other transformers...
);
Verbosity Levels and Conflict Handling:
- NONE (default): Creates a clean dependency tree without duplicate artifacts. Losing nodes are completely removed from the graph, so are cycles as well.
- STANDARD: Retains losing nodes for analysis but removes their children to prevent
duplicate dependencies. Special handling for version ranges: redundant nodes may still be removed
if multiple versions of the same artifact exist. Losing nodes link back to the winner via
NODE_DATA_WINNER
and preserve original scope/optionality information. This mode removes cycles only, while conflict nodes/duplicates are left in place. Graphs in this verbosity level cannot be resolved, their purpose is for analysis only. - FULL: Preserves the complete original graph structure including all conflicts and cycles. All nodes remain with their children, but conflict information is recorded for analysis. Graphs in this verbosity level cannot be resolved, their purpose is for analysis only.
CONFIG_PROP_VERBOSE
configuration property.
Conflict Metadata: In STANDARD and FULL modes, the keys NODE_DATA_ORIGINAL_SCOPE
and NODE_DATA_ORIGINAL_OPTIONALITY
are used to store the original scope and optionality of each node.
Obviously, dependency trees with verbosity STANDARD or FULL are not suitable for artifact resolution unless
a filter is employed to exclude the duplicate dependencies.
Conflict ID Processing Pipeline:
ConflictMarker
: Assigns conflict IDs based on GACE (groupId:artifactId:classifier:extension) coordinates, grouping artifacts that differ only in version (partitions the graph, assigning same conflict IDs to nodes belonging to same conflict group).ConflictIdSorter
: Creates topological ordering of conflict IDs and detects cycles- ConflictResolver implementation: Uses the sorted conflict IDs to resolve conflicts in dependency order
TransformationContextKeys.CONFLICT_IDS
,
TransformationContextKeys.SORTED_CONFLICT_IDS
, TransformationContextKeys.CYCLIC_CONFLICT_IDS
for
existing information about conflict ids. In absence of this information, it will automatically invoke the
ConflictIdSorter
to calculate it.- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic class
A context used to hold information that is relevant for resolving version and scope conflicts.static class
A conflicting dependency.static class
An extension point ofConflictResolver
that determines the effective optional flag of a dependency from a potentially conflicting set of derived optionalities.static class
A context used to hold information that is relevant for deriving the scope of a child dependency.static class
An extension point ofConflictResolver
that determines the scope of a dependency in relation to the scope of its parent.static class
An extension point ofConflictResolver
that determines the effective scope of a dependency from a potentially conflicting set ofderived scopes
.static enum
The enum representing verbosity levels of conflict resolver.static class
An extension point ofConflictResolver
that determines the winner among conflicting dependencies. -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final String
static final String
The name of the conflict resolver implementation to use: "path" (default) or "classic" (same as Maven 3).static final String
The key in the repository session'sconfiguration properties
used to store aBoolean
flag controlling the transformer's verbose mode.static final String
static final String
The key in the dependency node'scustom data
under which the optional flag of the dependency before derivation and conflict resolution is stored.static final String
The key in the dependency node'scustom data
under which the scope of the dependency before scope derivation and conflict resolution is stored.static final String
The key in the dependency node'scustom data
under which a reference to theDependencyNode
which has won the conflict is stored.static final String
-
Constructor Summary
ConstructorsModifierConstructorDescriptionprotected
No arg ctor for subclasses and default cases.ConflictResolver
(ConflictResolver.VersionSelector versionSelector, ConflictResolver.ScopeSelector scopeSelector, ConflictResolver.OptionalitySelector optionalitySelector, ConflictResolver.ScopeDeriver scopeDeriver) Creates a new conflict resolver instance with the specified hooks that delegates to configured conflict resolver dynamically. -
Method Summary
Modifier and TypeMethodDescriptionstatic ConflictResolver.Verbosity
getVerbosity
(RepositorySystemSession session) Helper method that usesRepositorySystemSession
andCONFIG_PROP_VERBOSE
key to figure out currentConflictResolver.Verbosity
: ifBoolean
orString
found, returnsConflictResolver.Verbosity.STANDARD
orConflictResolver.Verbosity.NONE
, depending on value (string is parsed withBoolean.parseBoolean(String)
fortrue
orfalse
correspondingly.transformGraph
(DependencyNode node, DependencyGraphTransformationContext context) Transforms the dependency graph denoted by the specified root node.
-
Field Details
-
CONFIG_PROP_VERBOSE
The key in the repository session'sconfiguration properties
used to store aBoolean
flag controlling the transformer's verbose mode. Accepted values are Boolean types, String type (where "true" would be interpreted astrue
) or Verbosity enum instances.- See Also:
- Sourced from:
RepositorySystemSession.getConfigProperties()
- Value type:
Object
- Default value:
- "NONE"
-
CONFIG_PROP_CONFLICT_RESOLVER_IMPL
The name of the conflict resolver implementation to use: "path" (default) or "classic" (same as Maven 3).- Since:
- 2.0.11
- See Also:
- Sourced from:
RepositorySystemSession.getConfigProperties()
- Value type:
String
- Default value:
DEFAULT_CONFLICT_RESOLVER_IMPL
-
CLASSIC_CONFLICT_RESOLVER
- See Also:
-
PATH_CONFLICT_RESOLVER
- See Also:
-
DEFAULT_CONFLICT_RESOLVER_IMPL
- See Also:
-
NODE_DATA_WINNER
The key in the dependency node'scustom data
under which a reference to theDependencyNode
which has won the conflict is stored.- See Also:
-
NODE_DATA_ORIGINAL_SCOPE
The key in the dependency node'scustom data
under which the scope of the dependency before scope derivation and conflict resolution is stored.- See Also:
-
NODE_DATA_ORIGINAL_OPTIONALITY
The key in the dependency node'scustom data
under which the optional flag of the dependency before derivation and conflict resolution is stored.- See Also:
-
-
Constructor Details
-
ConflictResolver
protected ConflictResolver()No arg ctor for subclasses and default cases. -
ConflictResolver
public ConflictResolver(ConflictResolver.VersionSelector versionSelector, ConflictResolver.ScopeSelector scopeSelector, ConflictResolver.OptionalitySelector optionalitySelector, ConflictResolver.ScopeDeriver scopeDeriver) Creates a new conflict resolver instance with the specified hooks that delegates to configured conflict resolver dynamically.- Parameters:
versionSelector
- The version selector to use, must not benull
.scopeSelector
- The scope selector to use, must not benull
.optionalitySelector
- The optionality selector ot use, must not benull
.scopeDeriver
- The scope deriver to use, must not benull
.
-
-
Method Details
-
getVerbosity
Helper method that usesRepositorySystemSession
andCONFIG_PROP_VERBOSE
key to figure out currentConflictResolver.Verbosity
: ifBoolean
orString
found, returnsConflictResolver.Verbosity.STANDARD
orConflictResolver.Verbosity.NONE
, depending on value (string is parsed withBoolean.parseBoolean(String)
fortrue
orfalse
correspondingly. This is to retain "existing" behavior, where the config key accepted only these values. Since 1.9.8 release, this key may containConflictResolver.Verbosity
enum instance as well, in which case that instance is returned. This method never returnsnull
. -
transformGraph
public DependencyNode transformGraph(DependencyNode node, DependencyGraphTransformationContext context) throws RepositoryException Description copied from interface:DependencyGraphTransformer
Transforms the dependency graph denoted by the specified root node. The transformer may directly change the provided input graph or create a new graph, the former is recommended for performance reasons.- Specified by:
transformGraph
in interfaceDependencyGraphTransformer
- Parameters:
node
- The root node of the (possibly cyclic!) graph to transform, must not benull
.context
- The graph transformation context, must not benull
.- Returns:
- The result graph of the transformation, never
null
. - Throws:
RepositoryException
- If the transformation failed.
-