Java 11 module-info:如何注册注解处理器
Java 11 module-info: how to register an annotation processor
要在 Java11 中注册服务提供商,可以使用以下 "provides" 模块信息条目:
module com.mycompany.mylib {
provides ServiceInterface with ServiceImpl;
}
然而,对于注释处理器,这似乎不起作用。 (注释处理器的特殊之处在于编译器应该在编译时而不是应用程序在运行时选择实现。)
为了对此进行测试,我创建了一些 SSCCEs on GitHub。
有 2 个模块:
java11-sample-annotation-processor
:提供@Foo
注解和FooApplicationProcessor
java11-sample-lib
: 提供了 2 个样本 类,都使用了 @Foo
注释
预期输出: 在 java11-sample-lib
JAR 中应该有一个 foo.txt
文件
master branch 中的版本是 有效的版本:
- Java 11
- 没有
module-info
使用
- 注释处理器在
src/main/resources/META-INF/services/javax.annotation.processing.Processor
中注册
在以下版本中,不会生成 foo.txt
文件:
在 registration-in-module-info branch 中,我已将 2 个库更改为 Java 11 个带有模块信息的模块。
注解处理器在这里注册在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 branch is a slight variation,我在这里指定了目标模块和目标包(硬编码)而不是根包。
在 registration-meta-inf branch 中仍然有一个模块信息,但注解处理器在 src/main/resources/META-INF/services/javax.annotation.processing.Processor
中注册,而不是在模块信息中(以防编译器无法使用 provides 中的语句模块信息!?)
在 only-one-module branch 中,我再次从 java11-sample-annotation-processor
中删除了模块信息。注释处理器在 src/main/resources/META-INF/services/javax.annotation.processing.Processor
.
中注册
所以我的问题是:在使用 Java 11 个模块时如何配置注释处理器?
过去,注释处理器在编译期间放置在 class 路径时会自动检测到。您可以从 javac
的 the documentation 中看到:
--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].
只要您使用 class-路径,情况仍然如此。然而,当使用模块路径时情况并非如此。要检测模块化注释处理器,您必须使用另一个选项明确指向它们:
--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.
没有提及用于自动检测注释处理器的模块路径。
要在 Java11 中注册服务提供商,可以使用以下 "provides" 模块信息条目:
module com.mycompany.mylib {
provides ServiceInterface with ServiceImpl;
}
然而,对于注释处理器,这似乎不起作用。 (注释处理器的特殊之处在于编译器应该在编译时而不是应用程序在运行时选择实现。)
为了对此进行测试,我创建了一些 SSCCEs on GitHub。
有 2 个模块:
java11-sample-annotation-processor
:提供@Foo
注解和FooApplicationProcessor
java11-sample-lib
: 提供了 2 个样本 类,都使用了@Foo
注释
预期输出: 在 java11-sample-lib
JAR 中应该有一个 foo.txt
文件
master branch 中的版本是 有效的版本:
- Java 11
- 没有
module-info
使用 - 注释处理器在
src/main/resources/META-INF/services/javax.annotation.processing.Processor
中注册
在以下版本中,不会生成 foo.txt
文件:
在 registration-in-module-info branch 中,我已将 2 个库更改为 Java 11 个带有模块信息的模块。 注解处理器在这里注册在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 branch is a slight variation,我在这里指定了目标模块和目标包(硬编码)而不是根包。
在 registration-meta-inf branch 中仍然有一个模块信息,但注解处理器在 src/main/resources/META-INF/services/javax.annotation.processing.Processor
中注册,而不是在模块信息中(以防编译器无法使用 provides 中的语句模块信息!?)
在 only-one-module branch 中,我再次从 java11-sample-annotation-processor
中删除了模块信息。注释处理器在 src/main/resources/META-INF/services/javax.annotation.processing.Processor
.
所以我的问题是:在使用 Java 11 个模块时如何配置注释处理器?
过去,注释处理器在编译期间放置在 class 路径时会自动检测到。您可以从 javac
的 the documentation 中看到:
--class-path
path,-classpath
path, or-cp
pathSpecifies 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 theCLASSPATH
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
pathSpecifies where to find annotation processors. If this option is not used, then the class path is searched for processors [emphasis added].
只要您使用 class-路径,情况仍然如此。然而,当使用模块路径时情况并非如此。要检测模块化注释处理器,您必须使用另一个选项明确指向它们:
--module-path
path or-p
pathSpecifies where to find application modules.
[...]
--processor-module-path
pathSpecifies the module path used for finding annotation processors.
没有提及用于自动检测注释处理器的模块路径。