Kirk Rader 1.0-SNAPSHOT
Annotation processing using reflection and instrumentation. More...
|Manual integration tests for the us.rader.logging package. |
|Status code extraction using reflection and instrumentation. |
|Aspects that inject logging into any application. |
|Instrumentation agent used to scan loaded classes. More...|
Annotation processing using reflection and instrumentation.
Java's reflection API supports:
I.e. given a set of instances of
Class<?>, one can use reflection to inspect those meta-objects for information about the corresponding types, including information about annotations. This begs the question: how does one obtain such a set of meta-objects?
If one already knows that a given class has been loaded as an explicit dependency at compile time, one can simply reference the relevant meta-object directly using syntax like
SomeType.class. Sometimes, however – and especially when writing tools to process custom annoations – one needs to dynamically load classes that are not explicit compile time dependencies and discover what classes were loaded at run time.
Baffingly enough, the reflection API is not sufficient to accomplish this. For reasons surpassing understanding, those responsible for Java's meta-object protocol chose to enable this most basic of functionality only through a separate API called instrumentation.
What this means is that only a class that has been configured to run as an instrumentation agent is supplied with an instance implementing the Instrumentation interface, and that is the only supported API that can answer the question, "what classes are currently loaded?" by way of its Instrumentation.getAllLoadedClasses() method.
That is the purpose of of the us.rader.logging.AnnotationsAgent class. In particular, it makes Instrumentation.getAllLoadedClasses() available as a static method when us.rader.logging.AnnotationsAgent is loaded via either the "premain" or "agent" mechanisms. This requires that the correct
Agent-Class entries appear in the JAR file's manifest from which us.rader.logging.AnnotationsAgent is loaded, as is accomplished by the
maven-jar-plugin configuration of the status-codes project's POM:
It also means that this feature can only be exploited when the JAR is loaded in the appropriate way at run time:
-javaagentparameter on the java command line, in which case the entry point specified by
Premain-Classwill be invoked
Agent-Classentry point in a running JVM
Note that the status-codes module can be used without installing its JAR as an instrumentation agent at run time, but this facility is supported where appropriate. For example, the module described by the Status Codes Maven Plugin page provides its own custom class loader – us.rader.logging.maven.DynamicClassLoader – which is an approach to discovering classes at run time suitable for a build tool like a Maven plugin.