Should an AbstractProcessor implementation return any annotation classes that may be annotated with a specific annotation not just fields

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

Leave a Comment