Suppose I have the following Java annotation processor:
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class MyProcessor extends AbstractProcessor {
private Messager messager;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
messager = processingEnv.getMessager();
}
@Override
public boolean process(
final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
for (TypeElement typeElement : annotations) {
validate(typeElement, roundEnv);
}
return false;
}
private void validate(TypeElement typeElement, RoundEnvironment roundEnv) {
for (Element element : roundEnv.getElementsAnnotatedWith(typeElement)) {
TypeMirror typeMirror = element.asType();
ElementKind elementKind = element.getKind();
if (elementKind.equals(ElementKind.ANNOTATION_TYPE)) {
System.out.println("ANNOTATION_TYPE");
validate((TypeElement) element, roundEnv);
} else if (elementKind.equals(ElementKind.FIELD)) {
System.out.println("FIELD");
if (!typeMirror.toString().equals(String.class.getName())) {
throw new RuntimeException("Not a valid type for annotation");
}
}
}
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public Set<String> getSupportedAnnotationTypes() {
final Set<String> annotations = new HashSet<>(Arrays.asList(MyCustomAnnotation.class.getName()));
return annotations;
}
}
MyCustomAnnotation.java
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Constraint(validatedBy = {})
public @interface MyCustomAnnotation {
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String message() default "{com.company.annotation.mycustomannotation}";
}
I can annotation a field in a POJO and it will cause FIELD
to be logged as part of the AbstractProcessor
execution:
public class SampleDTO {
@MyCustomAnnotation
private String text;
// ..
}
Which means that the annotation processor is executing fine and finding fields annotated with my annotation.
But when I add the annotation to a class definition, I don’t see ANNOTATION_TYPE
logged during AbstractProcessor
execution:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Constraint(validatedBy = {})
@MyCustomAnnotation
public @interface MyOtherAnnotation {
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String message() default "{com.company.annotation.myotherannotation}";
}
Shouldn’t I be able to find a reference to the MyOtherAnnotation
class since it contains MyCustomAnnotation
? I thought it should be included in results, not just fields containing the annotation