Class ConflictResolver
- java.lang.Object
-
- org.eclipse.aether.util.graph.transformer.ConflictResolver
-
- All Implemented Interfaces:
org.eclipse.aether.collection.DependencyGraphTransformer
- Direct Known Subclasses:
ClassicConflictResolver,PathConflictResolver
public class ConflictResolver extends java.lang.Object implements org.eclipse.aether.collection.DependencyGraphTransformer
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 ofConflictResolver.VersionSelector,ConflictResolver.ScopeSelector,ConflictResolver.OptionalitySelectorandConflictResolver.ScopeDeriver.Available Implementations:
ClassicConflictResolver- Original implementation (O(N²) worst-case)PathConflictResolver- Not yet recommended for production; high-performance implementation with O(N) complexity
Implementation Selection Guide:
- All projects: Use
ClassicConflictResolverfor optimal correctness and Maven 3.x behavior - Experimenters: Use
PathConflictResolverbut no guarantees it will work
Usage Example:
// Classic resolver 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_WINNERand 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_VERBOSEconfiguration property.Conflict Metadata: In STANDARD and FULL modes, the keys
NODE_DATA_ORIGINAL_SCOPEandNODE_DATA_ORIGINAL_OPTIONALITYare 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_IDSfor existing information about conflict ids. In absence of this information, it will automatically invoke theConflictIdSorterto calculate it.- See Also:
ClassicConflictResolver,PathConflictResolver
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classConflictResolver.ConflictContextA context used to hold information that is relevant for resolving version and scope conflicts.static classConflictResolver.ConflictItemA conflicting dependency.static classConflictResolver.OptionalitySelectorAn extension point ofConflictResolverthat determines the effective optional flag of a dependency from a potentially conflicting set of derived optionalities.static classConflictResolver.ScopeContextA context used to hold information that is relevant for deriving the scope of a child dependency.static classConflictResolver.ScopeDeriverAn extension point ofConflictResolverthat determines the scope of a dependency in relation to the scope of its parent.static classConflictResolver.ScopeSelectorAn extension point ofConflictResolverthat determines the effective scope of a dependency from a potentially conflicting set ofderived scopes.static classConflictResolver.VerbosityThe enum representing verbosity levels of conflict resolver.static classConflictResolver.VersionSelectorAn extension point ofConflictResolverthat determines the winner among conflicting dependencies.
-
Field Summary
Fields Modifier and Type Field Description static java.lang.StringAUTO_CONFLICT_RESOLVERstatic java.lang.StringCLASSIC_CONFLICT_RESOLVERstatic java.lang.StringCONFIG_PROP_CONFLICT_RESOLVER_IMPLThe name of the conflict resolver implementation to use: "auto" (default), "path", or "classic" (same as Maven 3).static java.lang.StringCONFIG_PROP_VERBOSEThe key in the repository session'sconfiguration propertiesused to store aBooleanflag controlling the transformer's verbose mode.static java.lang.StringDEFAULT_CONFLICT_RESOLVER_IMPLstatic java.lang.StringNODE_DATA_ORIGINAL_OPTIONALITYThe key in the dependency node'scustom dataunder which the optional flag of the dependency before derivation and conflict resolution is stored.static java.lang.StringNODE_DATA_ORIGINAL_SCOPEThe key in the dependency node'scustom dataunder which the scope of the dependency before scope derivation and conflict resolution is stored.static java.lang.StringNODE_DATA_WINNERThe key in the dependency node'scustom dataunder which a reference to theDependencyNodewhich has won the conflict is stored.static java.lang.StringPATH_CONFLICT_RESOLVER
-
Constructor Summary
Constructors Modifier Constructor Description protectedConflictResolver()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
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static ConflictResolver.VerbositygetVerbosity(org.eclipse.aether.RepositorySystemSession session)Helper method that usesRepositorySystemSessionandCONFIG_PROP_VERBOSEkey to figure out currentConflictResolver.Verbosity: ifBooleanorStringfound, returnsConflictResolver.Verbosity.STANDARDorConflictResolver.Verbosity.NONE, depending on value (string is parsed withBoolean.parseBoolean(String)fortrueorfalsecorrespondingly.org.eclipse.aether.graph.DependencyNodetransformGraph(org.eclipse.aether.graph.DependencyNode node, org.eclipse.aether.collection.DependencyGraphTransformationContext context)
-
-
-
Field Detail
-
CONFIG_PROP_VERBOSE
public static final java.lang.String CONFIG_PROP_VERBOSE
The key in the repository session'sconfiguration propertiesused to store aBooleanflag 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:
- Constant Field Values
-
CONFIG_PROP_CONFLICT_RESOLVER_IMPL
public static final java.lang.String CONFIG_PROP_CONFLICT_RESOLVER_IMPL
The name of the conflict resolver implementation to use: "auto" (default), "path", or "classic" (same as Maven 3).When set to "auto", the resolver will currently just use "classic". The idea here, is that this value will always select the best (most robust, most performant) one, which currently is "classic".
- Since:
- 2.0.11
- See Also:
- Constant Field Values
-
CLASSIC_CONFLICT_RESOLVER
public static final java.lang.String CLASSIC_CONFLICT_RESOLVER
- See Also:
- Constant Field Values
-
PATH_CONFLICT_RESOLVER
public static final java.lang.String PATH_CONFLICT_RESOLVER
- See Also:
- Constant Field Values
-
AUTO_CONFLICT_RESOLVER
public static final java.lang.String AUTO_CONFLICT_RESOLVER
- See Also:
- Constant Field Values
-
DEFAULT_CONFLICT_RESOLVER_IMPL
public static final java.lang.String DEFAULT_CONFLICT_RESOLVER_IMPL
- See Also:
- Constant Field Values
-
NODE_DATA_WINNER
public static final java.lang.String NODE_DATA_WINNER
The key in the dependency node'scustom dataunder which a reference to theDependencyNodewhich has won the conflict is stored.- See Also:
- Constant Field Values
-
NODE_DATA_ORIGINAL_SCOPE
public static final java.lang.String NODE_DATA_ORIGINAL_SCOPE
The key in the dependency node'scustom dataunder which the scope of the dependency before scope derivation and conflict resolution is stored.- See Also:
- Constant Field Values
-
NODE_DATA_ORIGINAL_OPTIONALITY
public static final java.lang.String NODE_DATA_ORIGINAL_OPTIONALITY
The key in the dependency node'scustom dataunder which the optional flag of the dependency before derivation and conflict resolution is stored.- See Also:
- Constant Field Values
-
-
Constructor Detail
-
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 benullscopeSelector- the scope selector to use, must not benulloptionalitySelector- the optionality selector ot use, must not benullscopeDeriver- the scope deriver to use, must not benull
-
-
Method Detail
-
getVerbosity
public static ConflictResolver.Verbosity getVerbosity(org.eclipse.aether.RepositorySystemSession session)
Helper method that usesRepositorySystemSessionandCONFIG_PROP_VERBOSEkey to figure out currentConflictResolver.Verbosity: ifBooleanorStringfound, returnsConflictResolver.Verbosity.STANDARDorConflictResolver.Verbosity.NONE, depending on value (string is parsed withBoolean.parseBoolean(String)fortrueorfalsecorrespondingly. This is to retain "existing" behavior, where the config key accepted only these values. Since 1.9.8 release, this key may containConflictResolver.Verbosityenum instance as well, in which case that instance is returned. This method never returnsnull.
-
transformGraph
public org.eclipse.aether.graph.DependencyNode transformGraph(org.eclipse.aether.graph.DependencyNode node, org.eclipse.aether.collection.DependencyGraphTransformationContext context) throws org.eclipse.aether.RepositoryException
- Specified by:
transformGraphin interfaceorg.eclipse.aether.collection.DependencyGraphTransformer- Throws:
org.eclipse.aether.RepositoryException
-
-