[英]The Java compiler does not allow usage of an annotation with `Source` retention from a `compileOnly` module for a project using JPMS
Annotation processors and compiler plugins often define annotations with source
or class
retention.注释处理器和编译器插件通常定义带有
source
或class
保留的注释。 These annotations are not exposed at runtime, thus there is no need to include them in the runtime classpath;这些注解不会在运行时暴露,因此不需要将它们包含在运行时类路径中; they can be used via
compileOnly
in a Gradle build file.它们可以通过
compileOnly
在 Gradle 构建文件中使用。 Additionally, there is no need to declare their use in the module-info
file.此外,无需在
module-info
文件中声明它们的用途。 Yet, in the presence of a module-info
file, the Java compiler requires the annotation classes to be included in the runtime classpath -- they must be declared in the module-info, which means they must be accessed from Gradle with implementation
instead of compileOnly
.然而,在存在
module-info
文件的情况下,Java 编译器要求注释类包含在运行时类路径中——它们必须在模块信息中声明,这意味着它们必须从 Gradle 访问,并使用implementation
而不是compileOnly
。 This appears to be a hole in the compiler's support for JPMS.这似乎是编译器对 JPMS 支持的一个漏洞。 Or, is there a good explanation for this odd behavior?
或者,对这种奇怪的行为有很好的解释吗?
Here's an example.这是一个例子。
package com.example;
...
@Retention(RetentionPolicy.SOURCE)
public @interface Example {
...
}
The com.example.Example
annotation is defined in dependency my-annotation-proc
. com.example.Example
注释在依赖my-annotation-proc
中定义。
dependencies {
compileOnly 'com.example:my-annotation-proc:0.1-SNAPSHOT'
annotationProcessor 'com.example:my-annotation-proc:0.1-SNAPSHOT'
}
Usage of ExampleAnnotation
in Foo.java.在 Foo.java 中使用
ExampleAnnotation
。
package abc;
public class Foo {
@com.example.Example
public void something() {
...
}
}
The module-info.java
file should not need a requires
for usage of the annotation. module-info.java
文件不需要使用requires
。
module MyProject {
// Should be no need for this.
// Plus, adding it requires an `implementation` dependency in Gradle, which brings it into runtime where it does not belong.
//requires my.annotation.proc;
}
Compiling the project produces a compile error indicating the com.example
is not visible etc.编译项目会产生编译错误,指示
com.example
不可见等。
A requires
directive is mandatory for any dependency, not just runtime dependencies.任何依赖项都必须使用
requires
指令,而不仅仅是运行时依赖项。
Compare with JLS, §7.7.1 :与JLS 比较,§7.7.1 :
7.7.1.
7.7.1. Dependences
依赖性
The
requires
directive specifies the name of a module on which the current module has a dependence.requires
指令指定当前模块所依赖的模块的名称。…
…
The
requires
keyword may be followed by the modifierstatic
.requires
关键字后面可以跟修饰符static
。 This specifies that the dependence, while mandatory at compile time, is optional at run time.这指定了依赖关系,虽然在编译时是必需的,但在运行时是可选的。
I don't know whether using requires static my.annotation.proc;
不知道使用是否
requires static my.annotation.proc;
solves your problem with Gradle, but that's how it is supposed to be handled at the language level.用 Gradle 解决了您的问题,但这就是应该在语言级别处理的方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.