quarkusio/quarkus · critical · DefinitionException
Quarkus does not support CDI Full @Specializes annotation; t
Error message
Quarkus does not support CDI Full @Specializes annotation; try using an @Alternative instead. If you want to mark one or more archives as Quarkus compatible, take a look at io.quarkus.arc.deployment.KnownCompatibleBeanArchiveBuildItem. Annotation was found in the following classes: <definitionErrors>
What it means
Quarkus Arc does not support CDI Full's @Specializes annotation. BeanArchiveProcessor.validateArchiveCompatibility scans bean archives for @Specializes and throws ArcDefinitionException (DefinitionException) listing the classes that declare it.
Source
Thrown at extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/BeanArchiveProcessor.java:192
validateArchiveCompatibility(rootArchive, rootArchive.getIndex(), knownCompatibleBeanArchives);
indexes.add(rootArchive.getIndex());
}
return CompositeIndex.create(indexes);
}
private void validateArchiveCompatibility(ApplicationArchive archive, IndexView index,
KnownCompatibleBeanArchives knownCompatibleBeanArchives) {
// check for occurrences of incompatible annotations - currently only @Specializes
Collection<AnnotationInstance> annotations = index.getAnnotations(DotNames.SPECIALIZES);
if (!annotations.isEmpty() && !knownCompatibleBeanArchives.isKnownCompatible(archive.getKey(),
KnownCompatibleBeanArchiveBuildItem.Reason.SPECIALIZES_ANNOTATION)) {
Set<String> definitionErrors = new HashSet<>();
for (AnnotationInstance annInstance : annotations) {
DotName targetClassName = annInstance.target().kind().equals(AnnotationTarget.Kind.CLASS)
? annInstance.target().asClass().name()
: annInstance.target().asMethod().declaringClass().name();
definitionErrors.add(targetClassName.toString());
throw new DefinitionException(
"Quarkus does not support CDI Full @Specializes annotation; try using an @Alternative instead. "
+
"If you want to mark one or more archives as Quarkus compatible, take a " +
"look at io.quarkus.arc.deployment.KnownCompatibleBeanArchiveBuildItem.\n" +
"Annotation was found in the following classes: " + definitionErrors);
}
}
}
private boolean isExplicitBeanArchive(ApplicationArchive archive) {
return archive.apply(tree -> tree.contains("META-INF/beans.xml") || tree.contains("WEB-INF/beans.xml"));
}
private boolean isImplicitBeanArchive(IndexView index, Set<DotName> beanDefiningAnnotations) {
// NOTE: Implicit bean archive without beans.xml contains one or more bean classes with a bean defining annotation and no extension
return index.getAllKnownImplementors(DotNames.EXTENSION).isEmpty()
&& index.getAllKnownImplementors(DotNames.BUILD_COMPATIBLE_EXTENSION).isEmpty()
&& containsBeanDefiningAnnotation(index, beanDefiningAnnotations);View on GitHub (pinned to e1c734241f)
Solutions
- Remove @Specializes and replace with @Alternative (plus @Priority) where appropriate
- Mark the archive as known-compatible via KnownCompatibleBeanArchiveBuildItem if the semantics are acceptable
- Exclude the offending dependency/archive from bean discovery
Example fix
// before
@Priority(1)
@Specializes
public class MyService extends BaseService { ... }
// after
@Priority(1)
@Alternative
public class MyService extends BaseService { ... } Defensive patterns
Strategy: validation
Validate before calling
Class<?> c = MySpecializingBean.class;
if (c.isAnnotationPresent(jakarta.enterprise.inject.Specializes.class))
throw new IllegalStateException("@Specializes is not supported by Quarkus: " + c.getName());
// or scan archives:
Index i = Index.of(MySpecializingBean.class);
if (!i.getAnnotations(DotName.createSimple("jakarta.enterprise.inject.Specializes")).isEmpty()) throw new IllegalStateException("@Specializes found"); Prevention
- Search dependencies for @Specializes before migrating to Quarkus
- Replace @Specializes with @Alternative + @Priority during porting
- Exclude incompatible CDI Full jars from bean discovery
When it happens
Trigger: A bean class (or a bean method's declaring class) in a bean archive uses @Specializes; the archive is not marked known-compatible and @Specializes is found on the application index.
Common situations: Porting a plain CDI (CDI Full/Weld) application to Quarkus; third-party jars containing @Specializes beans pulled in as dependencies.
Related errors
- IllegalStateException wrapping ClassNotFoundException for ge
- Unable to derive the logger name at ${injectionPoint}
- Improper integration of '${LogFilterFactory.class.getName()}
- Unable to construct type for ${btRemovedBean}: ${e.getMessag
- A context class must be a public non-abstract top-level or s
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/1bbb115c788bb62e.
Report an issue: GitHub.