apache/maven · error · IllegalArgumentException

The Typed annotation must contain only interfaces but the fo

Error message

The Typed annotation must contain only interfaces but the following types are not: ${nonInterfaces}

What it means

When SessionScope builds a proxy for a session-scoped implementation, it reads the interfaces to proxy from a @Typed annotation's value array. The proxy can only implement interfaces, so any listed type that is a class triggers IllegalArgumentException naming the offending classes. Either annotate with only interface types, or leave value empty so the component's directly-implemented interfaces are used.

Source

Thrown at impl/maven-impl/src/main/java/org/apache/maven/impl/di/SessionScope.java:136

    protected Class<?>[] getInterfaces(Class<?> superType) {
        if (superType.isInterface()) {
            return new Class<?>[] {superType};
        }
        for (Annotation a : superType.getAnnotations()) {
            Class<? extends Annotation> annotationType = a.annotationType();
            if (isTypeAnnotation(annotationType)) {
                try {
                    Class<?>[] value =
                            (Class<?>[]) annotationType.getMethod("value").invoke(a);
                    if (value.length == 0) {
                        // Only direct interfaces implemented by the class
                        value = superType.getInterfaces();
                    }
                    List<Class<?>> nonInterfaces =
                            Stream.of(value).filter(c -> !c.isInterface()).toList();
                    if (!nonInterfaces.isEmpty()) {
                        throw new IllegalArgumentException(
                                "The Typed annotation must contain only interfaces but the following types are not: "
                                        + nonInterfaces);
                    }
                    return value;
                } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                    throw new IllegalStateException(e);
                }
            }
        }
        throw new IllegalArgumentException(
                "The use of session scoped proxies require a org.apache.maven.api.di.Typed, org.eclipse.sisu.Typed or javax.enterprise.inject.Typed annotation");
    }

    protected boolean isTypeAnnotation(Class<? extends Annotation> annotationType) {
        return "org.apache.maven.api.di.Typed".equals(annotationType.getName());
    }

    /**

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Change the @Typed value to list interfaces only, e.g. @Typed(MyService.class) with MyService an interface
  2. Omit the value entirely (@Typed or @Typed({})) so the scope falls back to superType.getInterfaces()
  3. Re-check after refactors that no concrete class crept into the annotation

Example fix

// before
@SessionScoped
@Typed({MyService.class, MyServiceImpl.class})
public class MyServiceImpl implements MyService { ... }

// after
@SessionScoped
@Typed(MyService.class)
public class MyServiceImpl implements MyService { ... }
Defensive patterns

Strategy: validation

Validate before calling

// verify a @Typed value contains interfaces only, before the container creates the proxy
Typed typed = MyServiceImpl.class.getAnnotation(Typed.class);
if (typed != null) {
    for (Class<?> c : typed.value()) {
        if (!c.isInterface()) throw new IllegalStateException("@Typed lists non-interface: " + c.getName());
    }
}

Prevention

When it happens

Trigger: Annotating a session-scoped component with @Typed(SomeConcreteClass.class) or @Typed({MyApi.class, MyImpl.class}) where MyImpl is a class; copying a sisu @Typed listing from a non-proxied component onto a session-scoped one.

Common situations: Migrating components from Guice/Sisu bindings (where @Typed with classes was tolerated) into session scope; auto-generated annotations listing the implementation class; refactors that added the impl class to the Typed list.

Related errors


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