How do I use Annotation Processing API in runtime?
Solution 1
You can access the annotations at run time using reflection - getAnnotations.
To get a list of classes (in your classpath) using your annotation, you could - at runtime - iterate through all the classes testing if they have that annotation.
Alternatively - at build time - you could construct a class with a list of classes.
Solution 2
Did you specify that your annotation is available at runtime using the RetentionPolicy ? If not you need to use @Retention annotation on yours.
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String[] parameters();
String[] exceptions();
}
corgrath
Updated on June 27, 2022Comments
-
corgrath over 1 year
I have and followed several Annotation Processing Tool (APT) guides (such as 1 and 2) on the Internet and have managed to get it working in compiler/ build time, and even got it working in Eclipse.
Is there a way I can use APT in run time to get a list of Types (Classes) using my annotation.
I wrote something like:
@SupportedAnnotationTypes("com.domain.MyAnnotation") public class MyAbstractProcessor extends AbstractProcessor { public static Map<Element, MyAnnotation> patches = new HashMap<Element, MyAnnotation>(); @Override public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnvironment) { // Get all classes that has the annotation Set<? extends Element> classElements = roundEnvironment.getElementsAnnotatedWith(MyAnnotation.class); // For each class that has the annotation for (final Element classElement : classElements) { patches.put(classElement, annotation);
So MyAbstractProcessor.patches would be populate with a list of classes using the annotation. A noble idea, apart from the flaw that this APT is executing at build time, and not run time.
Is it even possible to use APT in run time?
Or am I using the wrong frameworks to get what I want?
-
corgrath over 11 years"Alternatively - at build time - you could construct a class with a list of classes." - You mean, output to a file which gets read by the application in run time?
-
emory over 11 yearsYes, use
processingEnv.getFiler().createSourceFile(qualifiedName).openWriter()
and write out the contents of patches to a static variable in thequalifedName
class. Of course you have to write all the required class boilerplate `public class simpleName { private static final Map < > patches = new Map < > { contents of patches } ... -
corgrath over 11 yearsYes, I did. Both SOURCE and RUNTIME :-)
-
zeropouet over 11 yearsNormally It should work, with this retention policy. If it is not working with APT, you might try JSR 269 (Pluggable Annotations Processing).
-
corgrath over 11 yearsWow, the createSourceFile is great. I didn't know that was possible. Thanks :-)
-
mostafa.S over 2 yearsquestion arises, imagine we write some runtime annotation processor with reflection, and present our whole library which includes our annotations, and some other guy uses our library in their own project. And he uses our annotations in his code, when our annotation runtime processing method is called and by whom? there should be some entry point for the runtime processor, right? or I am missing some key point?
-
emory over 2 years@mostafa.S Spring Boot is an example. I believe they use reflection to do annotation processing at runtime. I use Spring Boot in my own projects. I use Spring Boot annotations in my code (e.g., AT Service, AT Autowired, AT RestController, etc). The Spring Boot application is the entrypoint. You are correct, there is always some entry point.
-
mostafa.S over 2 years@emory yes, in case of Spring Boot, it is quite clear. because Spring boot application is called in main() method, so it can run the processor it self at any time it wants. but some other frameworks such as AT EnableKafka. does java runtime call their processor? it's a big ambiguity for me.