-processorpath & META-INF/services/javax.annotation.processing.Processor
Jesse Glick
jesse.glick at oracle.com
Thu Jan 26 05:44:40 PST 2012
A couple of other points on this topic I just thought of.
On 01/24/2012 06:02 AM, Jesse Glick wrote:
> It would be nice if [...when] module A provides javax.annotation.processing.Processor with some processor impl, then compilation of a module requiring A will run that
> processor if there are matching annotations
A longstanding irritation in 269 is that if as a library designer you do supply both an annotation and a matching processor, you have to choose between
1. Include the processor in the same module/JAR/etc. as the annotation (registered in ServiceLoader style). Ensures that everyone using the library (*) runs the processor
automatically. But makes the library a bit larger, and may introduce additional dependencies not used at runtime.
2. Place the processor in a different module. Keeps the library slimmer, but means that users will not have the processor run by default - they would need to check the
documentation of each library they use which defines any annotations and manually configure a processor path, which is unmaintainable when more than a couple of such
libraries are involved.
It would be a valuable improvement to let a library module declare that it has an associated processor module to be used only during compilation. Specifically, any module
requiring that library (incl. indirectly via "requires public") should include the processor module in its processorpath or equivalent. For example:
module lib {
exports lib;
requires processor service lib.proc; // syntax??
}
package lib;
public @interface Anno {}
module lib.proc {
requires lib;
provides service javax.annotation.processing.Processor with lib.proc.Proc;
}
package lib.proc;
@javax.annotation.processing.SupportedAnnotationTypes("lib.Anno")
public class Proc extends javax.annotation.processing.AbstractProcessor {...}
module user {
requires lib;
// "requires processor lib.proc" is implied
}
package user;
// lib.proc.Proc will be run on this:
@lib.Anno class C {}
(There probably needs to be some way of overriding processor discovery, like -proc:none or -processor only.This in current versions of javac.)
Another 269-related consideration is how processors will actually be run in JDK 8 javac. Currently the contents of -processorpath (defaulting to -classpath) are dumped
into a URLClassLoader and then ServiceLoader or the equivalent is used for discovery if -processor is not given. In a modular environment, you would expect each
ProcessingEnvironment to be associated with a transient LoaderPool (?) so that the semantics of the module system - especially dependencies and exported types - are used
for loading processors and their associated classes.
(The Javadoc of ProcessingEnvironment currently says "from the perspective of the running annotation processors, at least the chosen subset of helper classes are viewed
as being loaded by the same class loader"; this would need to be updated to refer to modules.)
TBD how modular javac should behave w.r.t. processors when run on an older JDK, as is the case for bootstrapping the JDK itself. If it knew how to resolve module
dependencies, it could fall back to computing the transitive closure of dependencies of all processor modules and creating a URLClassLoader. But if the JDK does not use
269 internally - or only in higher-level modules that can be built after javac has been bootstrapped - then this may not be an issue.
(*) Except Eclipse users in certain setups, as mentioned in the previous post.
More information about the jigsaw-dev
mailing list