2011-07-13 25 views
23

Estoy tratando de crear una nueva anotación con la cual haré algo de cableado de tiempo de ejecución, pero, por una serie de razones, me gustaría verificar en tiempo de compilación que mi cableado tendrá éxito con algunos controles rudimentarios.Creando un AbstractProcessor personalizado e integrando con Eclipse

Supongamos que crear una nueva anotación:

@Target(ElementType.FIELD) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface CustomAnnotation{ 
} 

Ahora quiero hacer algún tipo de validación en tiempo de compilación, como comprobar el campo que CustomAnnotation anota es de un tipo particular: ParticularType. Estoy trabajando en Java 6, por lo que creó un AbstractProcessor:

@SupportedAnnotationTypes("com.example.CustomAnnotation") 
public class CompileTimeAnnotationProcessor extends AbstractProcessor { 

    @Override 
    public boolean process(Set<? extends TypeElement> annotations, 
          RoundEnvironment roundEnv) { 
     Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(CustomAnnotation.class); 
     for(Element e : elements){ 
      if(!e.getClass().equals(ParticularType.class)){ 
       processingEnv.getMessager().printMessage(Kind.ERROR, 
        "@CustomAnnotation annotated fields must be of type ParticularType"); 
      } 
     } 
     return true; 
    } 

} 

Luego, sobre la base de algunas instrucciones que he encontrado, he creado una carpeta META-INF/services y ha creado un archivo con el contenido javax.annotation.processing.Processor:

com.example.CompileTimeAnnotationProcessor 

Luego, exporté el proyecto como un contenedor.

En otro proyecto, he construido un simple clase de prueba:

public class TestClass { 
    @CustomAnnotation 
    private String bar; // not `ParticularType` 
} 

He configurado las propiedades del proyecto Eclipse de la siguiente manera:

  • Conjunto compilador Java -> Tratamiento de anotación: "Habilitar el procesamiento de anotación" y "Habilitar el procesamiento en el editor"
  • Establecer el compilador Java -> Procesamiento de anotaciones -> Ruta de Fábrica para incluir mi jar exportado y comprobar en avanzado que aparece mi clase totalmente cualificada.

Hice clic en "aplicar" y las indicaciones de Eclipse para reconstruir el proyecto, presioné Aceptar, pero no se produce ningún error, a pesar de tener el procesador de anotación.

¿Dónde me equivoqué?


que corrió esta usando javac como

javac -classpath "..\bin;path\to\tools.jar" -processorpath ..\bin -processor com.example.CompileTimeAnnotationProcessor com\test\TestClass.java 

con la salida

campos @CustomAnnotation anotada deben ser del tipo ParticularType

+0

En primer lugar, ¿el procesador de anotación funciona con javac fuera de Eclipse? – antlersoft

+0

@antlersoft: sí, funciona fuera de Eclipse con javac directo (las ediciones reflejan esto). –

+4

¿Ha marcado el Registro de errores en Eclipse (Ventana> Mostrar vista> Registro de errores en caso de que no pueda verlo)? Cuando falla un procesador de anotaciones, es posible que no obtenga un cuadro de diálogo emergente con un error, pero aparecerá un error en el registro de errores. También puede intentar depurar su procesador en Eclipse rociando Messager.printMessage() con kind = NOTE en su procesador, ya que estos también aparecen en el registro de errores. – prunge

Respuesta

17

Para tener errores aparece en la editor, el Element causando t El error debe etiquetarse en la función printMessage. Para el ejemplo anterior, esto significa que la verificación del tiempo de compilación debe usar:

processingEnv.getMessager().printMessage(Kind.ERROR, 
    "@CustomAnnotation annotated fields must be of type ParticularType", 
    e); // note we explicitly pass the element "e" as the location of the error 
+1

Me tomó un tiempo descifrar, y como nota para futuros espectadores, la diferencia entre el "processingEnv.getMessager(). PrintMessage (" y el votado como la solución correcta es que se pasa un tercer argumento "e". – corgrath

+0

Gracias por la solución. Ya estaba a punto de lanzar mi procesador de anotación en el/bin, ¡pero ahora está funcionando genial! –