英文:
Java 11 module-info: how to register an annotation processor
问题
要在Java 11中注册一个服务提供者,可以使用以下"provides"模块信息(module-info)条目:
module com.mycompany.mylib {
provides ServiceInterface with ServiceImpl;
}
但是使用注解处理器似乎无法正常工作。(注解处理器的特殊之处在于,编译器应该在编译时选择实现,而不是在运行时选择应用程序。)
为了测试这一点,我在GitHub上创建了一些SSCCE:
有两个模块:
java11-sample-annotation-processor
:提供@Foo
注解和FooApplicationProcessor
java11-sample-lib
:提供两个示例类,都使用@Foo
注解
预期输出: 在java11-sample-lib
JAR中应该有一个foo.txt
文件
在master分支中的版本是有效的:
- Java 11
- 未使用
module-info
- 注解处理器在
src/main/resources/META-INF/services/javax.annotation.processing.Processor
中注册
在以下版本中,不会生成foo.txt
文件:
在registration-in-module-info分支中,我将两个库更改为使用Java 11模块和module-info。在这里,注解处理器在module-info中注册:
import com.github.puce77.java11annotationprocessortest.annotation.impl.FooApplicationProcessor;
module com.github.puce77.java11annotationprocessortest.annotation {
exports com.github.puce77.java11annotationprocessortest.annotation;
provides javax.annotation.processing.Processor with FooApplicationProcessor;
requires java.compiler;
}
在registration-in-module-info-moduleAndPkg分支中,是一个轻微的变化,我指定了目标模块和目标包(硬编码),而不是根包。
在registration-meta-inf分支中,两者仍然具有module-info,但是注解处理器是在src/main/resources/META-INF/services/javax.annotation.processing.Processor
中注册,而不是在module-info中(如果编译器无法处理module-info中的provides语句怎么办!?)
在only-one-module分支中,我再次从java11-sample-annotation-processor
中删除了module-info。注解处理器在src/main/resources/META-INF/services/javax.annotation.processing.Processor
中注册。
因此,我的问题是:在使用Java 11模块时,如何配置注解处理器?
英文:
To register a service provider in a Java 11 the following "provides" module-info entry can be used:
module com.mycompany.mylib {
provides ServiceInterface with ServiceImpl;
}
With annotation processors this doesn't seem to work, however. (The special thing with annotation processors is that it's the compiler which should pick up the implementation during compile time rather than the application during runtime.)
To test this out, I've created some SSCCEs on GitHub.
There are 2 modules:
java11-sample-annotation-processor
: provides the@Foo
annotation and theFooApplicationProcessor
java11-sample-lib
: provides 2 sample classes, both using the@Foo
annotation
Expected output: in the java11-sample-lib
JAR there should be a foo.txt
file
The version in the master branch is the one that works:
- Java 11
- no
module-info
used - annotation processor registration in
src/main/resources/META-INF/services/javax.annotation.processing.Processor
In the following versions the foo.txt
file is not generated:
In the registration-in-module-info branch I've changed the 2 libs to Java 11 modules with module-info.
The annotation processor is here registered in the module-info:
import com.github.puce77.java11annotationprocessortest.annotation.impl.FooApplicationProcessor;
module com.github.puce77.java11annotationprocessortest.annotation {
exports com.github.puce77.java11annotationprocessortest.annotation;
provides javax.annotation.processing.Processor with FooApplicationProcessor;
requires java.compiler;
}
The registration-in-module-info-moduleAndPkg branch is a slight variation, where I specified the target module and target package (hardcoded) rather than the root package.
In the registration-meta-inf branch still both have a module-info but the annotation processor is registered in src/main/resources/META-INF/services/javax.annotation.processing.Processor
rather than in the module-info (in case the compiler can not work with provides statements in the module-info!?)
In the only-one-module branch I've removed the module-info from the java11-sample-annotation-processor
again. The annotation processor is registered in src/main/resources/META-INF/services/javax.annotation.processing.Processor
.
So my question: how can I configure an annotation processor when working with Java 11 modules?
答案1
得分: 4
过去,在编译过程中将注解处理器放置在类路径上时,注解处理器会被自动检测到。您可以从javac
的文档中看到这一点:
--class-path
path、-classpath
path 或-cp
path指定查找用户类文件和注解处理器的位置 [已加重]。该类路径会覆盖
CLASSPATH
环境变量中的用户类路径。
- 如果未指定
--class-path
、-classpath
或-cp
,则用户类路径为CLASSPATH
环境变量的值,如果设置了的话,否则为当前目录。- 如果未为模块编译代码,且未指定
--source-path
或-sourcepath
选项,则还会在用户类路径中查找源文件。- 如果未指定
-processorpath
选项,则也会在类路径中查找注解处理器 [已加重]。[...]
--processor-path
path 或-processorpath
path指定查找注解处理器的位置。如果未使用此选项,则会在类路径中查找处理器 [已加重]。
只要您使用类路径,这仍然适用。然而,在使用模块路径时情况就不同了。为了检测到模块化注解处理器,您必须使用另一个选项明确指向它们:
--module-path
path 或-p
path指定查找应用程序模块的位置。
[...]
--processor-module-path
path指定用于查找注解处理器的模块路径。
没有提到会使用模块路径自动检测注解处理器。
英文:
It used to be that annotation processors were automatically detected when placed on the class-path during compilation. You can see this from the documentation of javac
:
>--class-path
path, -classpath
path, or -cp
path
>
> Specifies where to find user class files and annotation processors [emphasis added]. This class path overrides the user class path in the CLASSPATH
environment variable.
>
>* If --class-path
, -classpath
, or -cp
are not specified, then the user class path is the value of the CLASSPATH
environment variable, if that is set, or else the current directory.
>* If not compiling code for modules, if the --source-path
or -sourcepath
option is not specified, then the user class path is also searched for source files.
>* If the -processorpath
option is not specified, then the class path is also searched for annotation processors [emphasis added].
>
>[...]
>
>--processor-path
path or -processorpath
path
>
>Specifies where to find annotation processors. If this option is not used, then the class path is searched for processors [emphasis added].
And this is still the case as long as you're using the class-path. This is not the case, however, when using the module-path. For modular annotation processors to be detected you have to explicitly point to them with another option:
>--module-path
path or -p
path
>
>Specifies where to find application modules.
>
> [...]
>
>--processor-module-path
path
>
>Specifies the module path used for finding annotation processors.
No mention of the module-path being used to automatically detect annotation processors.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论