Estoy tratando de crear una nueva anotación con la que voy a hacer un poco de tiempo de ejecución de cableado, pero, por una serie de razones, me gustaría comprobar en tiempo de compilación que mi cableado será un éxito con algunos rudimentarios de cheques.

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, así que he creado 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;
    }

}

A continuación, basándose en algunas instrucciones que he encontrado, he creado una carpeta META-INF/services y crea un archivo javax.annotation.processing.Processor con contenido:

 com.example.CompileTimeAnnotationProcessor

Entonces, he exportado el proyecto como un tarro.

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

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

He configurado el proyecto de Eclipse propiedades como sigue:

  • Conjunto Compilador de Java -> Anotación de Procesamiento: «Habilitar la anotación de procesamiento» y «Habilitar el procesamiento en el editor de»
  • Conjunto Compilador de Java -> Anotación de Procesamiento -> la Fábrica de Ruta para incluir mi exportado frasco y se examina bajo avanzado que mi clase completo se muestra.

Hice clic en «aplicar» y Eclipse le pide volver a generar el proyecto, me golpeó bien … pero no se produce ningún error, a pesar de tener la anotación del procesador.

Donde ¿qué hice mal?


Me encontré con esto el uso de javac como

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

con salida

@CustomAnnotation anotado campos deben ser del tipo ParticularType

  • En primer lugar, hace la anotación de trabajo del procesador con javac fuera de Eclipse?
  • sí, funciona fuera de Eclipse con la recta javac (ediciones reflejar este).
  • Has comprobado el Registro de Errores en Eclipse (Ventana > Ver > Registro de Error en caso de que usted no lo puede ver)? Cuando una anotación procesador falla, puede ser que no consiga un cuadro de diálogo emergente con un error, pero obtendrá un error que aparece en el registro de errores. Usted también puede tratar de depurar el procesador en Eclipse por aspersión, Messager.printMessage() con tipo=NOTA en su procesador, ya que estas se muestran en el registro de errores así.
  • Hace la anotación procesador FRASCO que han construido la ParicularType y CustomAnnotation clases en ella? Si no, usted podría estar recibiendo NoClassDefFoundErrors cuando el procesador se ejecuta en Eclipse.
  • de hecho, el error no se muestran en el Registro de Errores, hay una manera de obtener el error más severas? Decir, en la clase de vista del editor o, al menos, en el panel de «Problemas»?
InformationsquelleAutor Mark Elliot | 2011-07-13

1 Comentario

  1. 17

    Tiene errores se muestran en el editor, el Element causando el error debe ser etiquetado en el printMessage función. Para el ejemplo anterior, esto significa que el tiempo de compilación de verificación debe utilizar:

    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
    • Me tomó un tiempo para averiguar, y como nota para el futuro de los espectadores, la diferencia entre el autor del «processingEnv.getMessager().printMessage(» y la votaron como la solución correcta es que un tercer argumento de la «e» es pasado.
    • Gracias por la solución. Yo ya estaba a punto de tirar mi anotación del procesador en el /bin, pero ahora es un gran trabajo!

Dejar respuesta

Please enter your comment!
Please enter your name here