Skip to content

Commit

Permalink
Merge pull request #31581 from manovotn/wrongAnnotationStaticMethod
Browse files Browse the repository at this point in the history
Arc - Do not validate static members in inner non-static classes for CDI annotations
  • Loading branch information
manovotn authored Mar 6, 2023
2 parents d8c2e78 + 5d3a353 commit 4a678b6
Showing 1 changed file with 53 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.ClassInfo.NestingType;
import org.jboss.jandex.DotName;
import org.jboss.jandex.FieldInfo;
import org.jboss.jandex.IndexView;
import org.jboss.jandex.MethodInfo;

import io.quarkus.arc.deployment.ValidationPhaseBuildItem.ValidationErrorBuildItem;
import io.quarkus.arc.processor.Annotations;
Expand Down Expand Up @@ -72,35 +74,66 @@ void detect(ArcConfig config, ApplicationIndexBuildItem applicationIndex, Custom
NestingType nestingType = clazz.nestingType();
if (NestingType.ANONYMOUS == nestingType || NestingType.LOCAL == nestingType
|| (NestingType.INNER == nestingType && !Modifier.isStatic(clazz.flags()))) {
// Annotations declared on the class, incl. the annotations added via transformers
Collection<AnnotationInstance> classAnnotations = transformedAnnotations.getAnnotations(clazz);
if (classAnnotations.isEmpty() && clazz.annotationsMap().isEmpty()) {
continue;
}
if (scopeAnnotations.isScopeIn(classAnnotations)) {
// Annotations declared on the class level, incl. the annotations added via transformers
Collection<AnnotationInstance> classLevelAnnotations = transformedAnnotations.getAnnotations(clazz);
if (scopeAnnotations.isScopeIn(classLevelAnnotations)) {
validationErrors.produce(new ValidationErrorBuildItem(
new IllegalStateException(String.format(
"The %s class %s has a scope annotation but it must be ignored per the CDI rules",
clazz.nestingType().toString(), clazz.name().toString()))));
} else if (clazz.annotationsMap().containsKey(DotNames.OBSERVES)) {
validationErrors.produce(new ValidationErrorBuildItem(
new IllegalStateException(String.format(
"The %s class %s declares an observer method but it must be ignored per the CDI rules",
clazz.nestingType().toString(), clazz.name().toString()))));
} else if (clazz.annotationsMap().containsKey(DotNames.PRODUCES)) {
validationErrors.produce(new ValidationErrorBuildItem(
new IllegalStateException(String.format(
"The %s class %s declares a producer but it must be ignored per the CDI rules",
clazz.nestingType().toString(), clazz.name().toString()))));
} else if (Annotations.containsAny(classAnnotations, interceptorResolverBuildItem.getInterceptorBindings())
|| Annotations.containsAny(clazz.annotations(),
interceptorResolverBuildItem.getInterceptorBindings())) {
// detect interceptor bindings on nested classes
} else if (Annotations.containsAny(classLevelAnnotations,
interceptorResolverBuildItem.getInterceptorBindings())) {
// detect interceptor bindings declared at nested class level
validationErrors.produce(new ValidationErrorBuildItem(
new IllegalStateException(String.format(
"The %s class %s declares an interceptor binding but it must be ignored per CDI rules",
clazz.nestingType().toString(), clazz.name().toString()))));
}

// iterate over methods and verify those
// note that since JDK 16, you can have static method inside inner non-static class
for (MethodInfo methodInfo : clazz.methods()) {
// annotations declared on method level, incl. the annotations added via transformers
Collection<AnnotationInstance> methodAnnotations = transformedAnnotations.getAnnotations(methodInfo);
if (methodAnnotations.isEmpty()) {
continue;
}
if (Annotations.contains(methodAnnotations, DotNames.OBSERVES)
|| Annotations.contains(methodAnnotations, DotNames.OBSERVES_ASYNC)) {
validationErrors.produce(new ValidationErrorBuildItem(
new IllegalStateException(String.format(
"The method %s in the %s class %s declares an observer method but it must be ignored per the CDI rules",
methodInfo.name(), clazz.nestingType().toString(), clazz.name().toString()))));
} else if (Annotations.contains(methodAnnotations, DotNames.PRODUCES)) {
validationErrors.produce(new ValidationErrorBuildItem(
new IllegalStateException(String.format(
"The method %s in the %s class %s declares a producer but it must be ignored per the CDI rules",
methodInfo.name(), clazz.nestingType().toString(), clazz.name().toString()))));
} else if (!Modifier.isStatic(methodInfo.flags()) && Annotations.containsAny(methodAnnotations,
interceptorResolverBuildItem.getInterceptorBindings())) {
// detect interceptor bindings declared at nested class methods
validationErrors.produce(new ValidationErrorBuildItem(
new IllegalStateException(String.format(
"The method %s in the %s class %s declares an interceptor binding but it must be ignored per CDI rules",
methodInfo.name(), clazz.nestingType().toString(), clazz.name().toString()))));
}

}

// iterate over all fields, check for incorrect producer declarations
for (FieldInfo fieldInfo : clazz.fields()) {
// annotations declared on field level, incl. the annotations added via transformers
Collection<AnnotationInstance> fieldAnnotations = transformedAnnotations.getAnnotations(fieldInfo);
if (fieldAnnotations.isEmpty()) {
continue;
}
if (Annotations.contains(fieldAnnotations, DotNames.PRODUCES)) {
validationErrors.produce(new ValidationErrorBuildItem(
new IllegalStateException(String.format(
"The field %s in the %s class %s declares a producer but it must be ignored per the CDI rules",
fieldInfo.name(), clazz.nestingType().toString(), clazz.name().toString()))));
}
}
}
}
}
Expand Down

0 comments on commit 4a678b6

Please sign in to comment.