Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Java
  4. Compile-time Annotation Processing [Solved]

Compile-time Annotation Processing [Solved]

Scheduled Pinned Locked Moved Java
helpjavatutorialquestionworkspace
2 Posts 1 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Skippums
    wrote on last edited by
    #1

    I am attempting to generate a compile-time error if a subclass does not define a specific static field with a type subclassed from a defined Class field in the annotation. For example:

    // RequiredStaticField.java
    import java.lang.annotation.*;

    @Retention(RetentionPolicy.SOURCE)
    @Target(ElementType.TYPE)
    @Inherited
    public @interface RequiredStaticField {
    public String name();
    public Class type();
    }

    // MyClass.java
    @RequiredStaticField(name="StaticField", type=Number.class)
    public class MyClass {
    private static Integer StaticField;
    }

    The classes above should validate and compile. However, I am having trouble determining if "Integer" is a subtype of "Number" in my AbstractProcessor implementation...

    // RequiredStaticFieldProcessor.java
    import java.util.Set;

    import javax.annotation.processing.*;
    import javax.lang.model.element.*;
    import javax.lang.model.util.Types;

    @SupportedAnnotationTypes("NAMESPACE.RequiredStaticField");
    public class RequiredStaticFieldProcessor extends AbstractProcessor {
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment environment) {
    // Get all classes that have the annotation
    Set<? extends Element> elementsWithAnnotation =
    environment.getElementsAnnotatedWith(RequiredStaticField.class);
    for (Element elementWithAnnotation : elementsWithAnnotation) {
    // If the element kind is not ElementKind.CLASS, display warning and continue
    // If the class is abstract, continue
    boolean isFound = false;
    RequiredStaticMethod annotation = elementWithAnnotation
    .getAnnotation(RequiredStaticMethod.class);
    for (Element member : elementWithAnnotation.getEnclosedElements()) {
    // If not a field, continue
    // If the field has the wrong name, continue

                // THIS IS WHERE I NEED HELP!  The following does not compile.
                // In the following, I either need to get the Class
                // of member.asType(), or I need to iterate through the superclasses
                // of member.asType(), or I need to convert annotation.type()
                // to a TypeMirror object. Any Ideas?
                isFound = Types.isSubType(member.asType(), annotation.type());
    
                if (isFound) {
                    break;
                } else {
                    // Display error about declari
    
    S 1 Reply Last reply
    0
    • S Skippums

      I am attempting to generate a compile-time error if a subclass does not define a specific static field with a type subclassed from a defined Class field in the annotation. For example:

      // RequiredStaticField.java
      import java.lang.annotation.*;

      @Retention(RetentionPolicy.SOURCE)
      @Target(ElementType.TYPE)
      @Inherited
      public @interface RequiredStaticField {
      public String name();
      public Class type();
      }

      // MyClass.java
      @RequiredStaticField(name="StaticField", type=Number.class)
      public class MyClass {
      private static Integer StaticField;
      }

      The classes above should validate and compile. However, I am having trouble determining if "Integer" is a subtype of "Number" in my AbstractProcessor implementation...

      // RequiredStaticFieldProcessor.java
      import java.util.Set;

      import javax.annotation.processing.*;
      import javax.lang.model.element.*;
      import javax.lang.model.util.Types;

      @SupportedAnnotationTypes("NAMESPACE.RequiredStaticField");
      public class RequiredStaticFieldProcessor extends AbstractProcessor {
      @Override
      public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment environment) {
      // Get all classes that have the annotation
      Set<? extends Element> elementsWithAnnotation =
      environment.getElementsAnnotatedWith(RequiredStaticField.class);
      for (Element elementWithAnnotation : elementsWithAnnotation) {
      // If the element kind is not ElementKind.CLASS, display warning and continue
      // If the class is abstract, continue
      boolean isFound = false;
      RequiredStaticMethod annotation = elementWithAnnotation
      .getAnnotation(RequiredStaticMethod.class);
      for (Element member : elementWithAnnotation.getEnclosedElements()) {
      // If not a field, continue
      // If the field has the wrong name, continue

                  // THIS IS WHERE I NEED HELP!  The following does not compile.
                  // In the following, I either need to get the Class
                  // of member.asType(), or I need to iterate through the superclasses
                  // of member.asType(), or I need to convert annotation.type()
                  // to a TypeMirror object. Any Ideas?
                  isFound = Types.isSubType(member.asType(), annotation.type());
      
                  if (isFound) {
                      break;
                  } else {
                      // Display error about declari
      
      S Offline
      S Offline
      Skippums
      wrote on last edited by
      #2

      Figured it out: you can't access an annotation field of type Class<?> at compile-time. Attempting to do so results in a MirroredTypeException. Instead, pass the class in as a string containing the fully-qualified name of the type, and use the following code to get the TypeMirror for that type:

      MyAnnotation annotation = elementWithAnnotation.getAnnotation(MyAnnotation.class);
      // type is a string...
      Element typeDeclaration = processingEnv.getElementUtils().getTypeElement(annotation.type());
      if (typeDeclaration == null) {
      // The type could not be found
      } else {
      // Do something with typeDeclaration.asType()
      }

      Hope this helps,

      Sounds like somebody's got a case of the Mondays -Jeff

      1 Reply Last reply
      0
      Reply
      • Reply as topic
      Log in to reply
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes


      • Login

      • Don't have an account? Register

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • World
      • Users
      • Groups