apache/maven · error · PluginContainerException
Error in component graph of plugin ${plugin.getId()}: ${e.ge
Error message
Error in component graph of plugin ${plugin.getId()}: ${e.getMessage()} What it means
While setting up the plugin realm, Sisu/Plexus component discovery over the plugin's classes failed with ComponentLookupException or CycleDetectedInComponentGraphException: the plugin's components (discovered via annotations) form a dependency cycle or reference a component that cannot be satisfied. Maven wraps this in PluginContainerException naming the plugin and realm.
Source
Thrown at impl/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java:457
if (pluginDescriptor != null) {
for (MojoDescriptor mojo : pluginDescriptor.getMojos()) {
if (!mojo.isV4Api()) {
mojo.setRealm(pluginRealm);
container.addComponentDescriptor(mojo);
}
}
}
Thread.currentThread().setContextClassLoader(pluginRealm);
((DefaultPlexusContainer) container)
.discoverComponents(
pluginRealm,
new SessionScopeModule(container.lookup(SessionScope.class)),
new MojoExecutionScopeModule(container.lookup(MojoExecutionScope.class)),
new PluginConfigurationModule(plugin.getDelegate()),
new SisuDiBridgeModule(true));
} catch (ComponentLookupException | CycleDetectedInComponentGraphException e) {
throw new PluginContainerException(
plugin,
pluginRealm,
"Error in component graph of plugin " + plugin.getId() + ": " + e.getMessage(),
e);
} finally {
Thread.currentThread().setContextClassLoader(prevTccl);
}
}
private List<org.eclipse.aether.artifact.Artifact> toAetherArtifacts(final List<Artifact> pluginArtifacts) {
return new ArrayList<>(RepositoryUtils.toArtifacts(pluginArtifacts));
}
private List<Artifact> toMavenArtifacts(DependencyResult dependencyResult) {
return dependencyResult.getDependencyNodeResults().stream()
.filter(n -> n.getArtifact().getPath() != null)
.map(n -> RepositoryUtils.toArtifact(n.getDependency()))
.toList();View on GitHub (pinned to e4093d4e12)
Solutions
- Read the message - the cycle path lists the components in the loop, or the lookup error names the missing role.
- Break the cycle: inject Provider<T> or do a lazy lookup on one side of the loop instead of a direct reference.
- Remove or exclude the plugin dependency that drags foreign components into the realm.
- Upgrade the plugin - many component-graph issues are fixed upstream.
Example fix
// before: cycle
@Named class A { @Inject B b; }
@Named class B { @Inject A a; }
// after: break the cycle with a Provider
@Named class A { @Inject B b; }
@Named class B { private final Provider<A> a; @Inject B(Provider<A> a) { this.a = a; } } Defensive patterns
Strategy: validation
Validate before calling
// junit smoke test in the plugin's own build: fail on wiring problems at build time
@Test void componentGraphIsAcyclic() throws Exception {
Injector injector = Guice.createInjector(
new WireModule(new ClassSpaceModule(new URLClassSpace(getClass().getClassLoader()))));
injector.getAllBindings(); // eager scan surfaces cycles/missing roles now, not in users' builds
} Try / catch
try {
pluginManager.getConfiguredMojo(mojoInterface, session, mojoExecution);
} catch (PluginContainerException e) {
Throwable c = e.getCause();
if (c instanceof CycleDetectedInComponentGraphException) {
// report the cycle path and the plugin id instead of failing the whole build silently
log.error("component cycle in {}: {}", mojoExecution.getPlugin(), c.getMessage());
}
throw e;
} Prevention
- Prefer constructor injection and break cycles with Provider<T>
- Smoke-test component wiring in the plugin's unit tests
- Never add another plugin's jar as a dependency of your plugin
When it happens
Trigger: Two components in the plugin inject each other directly or through a chain; a @Named/@Component role has no implementation available in the realm; plugin dependencies contribute extra plexus components that conflict or complete a cycle.
Common situations: Plugin refactors introducing mutually-dependent components; depending on another plugin's jar and doubling its components into the realm; constructor-injection cycles introduced while 'cleaning up' wiring.
Related errors
- Unable to load the mojo '${mojoDescriptor.getGoal()}' (or on
- Cannot read metadata from '{}'
- Unable to lookup org.eclipse.aether.RepositorySystem
- %nThere can only be one user supplied ConfigurationProcessor
- No binding to construct an instance for key {}. Existing bi
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/20ca0f2df61db607.
Report an issue: GitHub.