apache/maven · error · DIException

Cannot rebind scope annotation class to a different implemen

Error message

Cannot rebind scope annotation class to a different implementation: {}

What it means

bindScope associates a scope annotation (Singleton, per-lookup, custom) with its Scope implementation. Scopes live in a map keyed by annotation class; if the annotation was already registered, scopes.put returns the previous entry and the injector throws DIException. Despite the message saying 'different implementation', any second bindScope for the same annotation fails.

Source

Thrown at impl/maven-di/src/main/java/org/apache/maven/di/impl/InjectorImpl.java:129

                }
            }
        } catch (Exception e) {
            throw new DIException("Error while discovering DI classes from classLoader", e);
        }
        return this;
    }

    @Nonnull
    @Override
    public Injector bindScope(@Nonnull Class<? extends Annotation> scopeAnnotation, @Nonnull Scope scope) {
        return bindScope(scopeAnnotation, () -> scope);
    }

    @Nonnull
    @Override
    public Injector bindScope(@Nonnull Class<? extends Annotation> scopeAnnotation, @Nonnull Supplier<Scope> scope) {
        if (scopes.put(scopeAnnotation, scope) != null) {
            throw new DIException(
                    "Cannot rebind scope annotation class to a different implementation: " + scopeAnnotation);
        }
        return this;
    }

    @Nonnull
    @Override
    public <U> Injector bindInstance(@Nonnull Class<U> clazz, @Nonnull U instance) {
        Key<?> key = Key.of(clazz, ReflectionUtils.qualifierOf(clazz));
        Binding<U> binding = Binding.toInstance(instance);
        return doBind(key, binding);
    }

    @Override
    public <U> Injector bindSupplier(@Nonnull Class<U> clazz, @Nonnull Supplier<U> supplier) {
        Key<?> key = Key.of(clazz, ReflectionUtils.qualifierOf(clazz));
        Binding<U> binding = Binding.toSupplier(supplier);
        return doBind(key, binding);

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Locate the duplicate: the message names the annotation class — search every bindScope call for it
  2. Bind each scope annotation exactly once per injector and centralize scope setup in one bootstrap place
  3. Create a fresh injector per application or test instead of re-configuring a shared one

Example fix

// before
injector.bindScope(Singleton.class, singletonScope); // second registration -> DIException

// after
Set<Class<? extends Annotation>> registered = new HashSet<>();
if (registered.add(Singleton.class)) {
    injector.bindScope(Singleton.class, singletonScope);
}
Defensive patterns

Strategy: validation

Validate before calling

private final Set<Class<? extends Annotation>> boundScopes = new HashSet<>();

void bindScopeOnce(Injector injector, Class<? extends Annotation> anno, Scope scope) {
    if (boundScopes.add(anno)) {
        injector.bindScope(anno, scope);
    }
}

Try / catch

try {
    injector.bindScope(Singleton.class, scope);
} catch (DIException e) {
    // annotation already registered: skip or reuse the existing scope registration
    log.debug("scope already bound: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Two bindScope calls with the same annotation class on one injector — e.g. two extensions or bootstrap modules each registering @Singleton, or re-running configuration against a shared injector.

Common situations: Adding a custom scope that a core module already binds; plexus-to-DI migrations double-registering scopes; tests that reuse a global injector across different configurations.

Related errors


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