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

  1. Read the message - the cycle path lists the components in the loop, or the lookup error names the missing role.
  2. Break the cycle: inject Provider<T> or do a lazy lookup on one side of the loop instead of a direct reference.
  3. Remove or exclude the plugin dependency that drags foreign components into the realm.
  4. 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

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


AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21). Data as JSON: /api/errors/20ca0f2df61db607. Report an issue: GitHub.