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
- Change the @Typed value to list interfaces only, e.g. @Typed(MyService.class) with MyService an interface
- Omit the value entirely (@Typed or @Typed({})) so the scope falls back to superType.getInterfaces()
- 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
- List only interfaces in @Typed on session-scoped components
- Leave @Typed value empty to auto-use the class's direct interfaces
- Add a classpath test asserting @Typed values of all @SessionScoped components are interfaces
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
- The use of session scoped proxies require a org.apache.maven
- Cannot rebind scope annotation class to a different implemen
- No instance of {} is bound to the mojo execution scope.
- Cannot access {} outside of a scoping block
- Cannot access session scope outside of a scoping block
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/6da3a223189e16d6.
Report an issue: GitHub.