Java 编译器不允许在使用 JPMS 的项目中使用来自“compileOnly”模块的带有“Source”保留的注释
The Java compiler does not allow usage of an annotation with `Source` retention from a `compileOnly` module for a project using JPMS
注释处理器和编译器插件通常定义具有 source
或 class
保留的注释。这些注解不会在运行时公开,因此不需要将它们包含在运行时类路径中;它们可以通过 compileOnly
在 Gradle 构建文件中使用。此外,无需在 module-info
文件中声明它们的用途。然而,在存在 module-info
文件的情况下,Java 编译器要求将注释 类 包含在运行时类路径中——它们必须在模块信息中声明,这意味着必须使用 implementation
而不是 compileOnly
从 Gradle 访问它们。这似乎是编译器对 JPMS 的支持中的一个漏洞。或者,对于这种奇怪的行为有什么好的解释吗?
这是一个例子。
package com.example;
...
@Retention(RetentionPolicy.SOURCE)
public @interface Example {
...
}
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'
}
ExampleAnnotation
在 Foo.java 中的用法。
package abc;
public class Foo {
@com.example.Example
public void something() {
...
}
}
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;
}
编译项目会产生编译错误,指示 com.example
不可见等
requires
指令对于 任何 依赖项都是强制性的,而不仅仅是运行时依赖项。
与JLS, §7.7.1比较:
7.7.1. Dependences
The requires
directive specifies the name of a module on which the current module has a dependence.
…
The requires
keyword may be followed by the modifier static
. This specifies that the dependence, while mandatory at compile time, is optional at run time.
我不知道使用 requires static my.annotation.proc;
是否可以解决您使用 Gradle 的问题,但这应该是在语言级别处理的方式。
注释处理器和编译器插件通常定义具有 source
或 class
保留的注释。这些注解不会在运行时公开,因此不需要将它们包含在运行时类路径中;它们可以通过 compileOnly
在 Gradle 构建文件中使用。此外,无需在 module-info
文件中声明它们的用途。然而,在存在 module-info
文件的情况下,Java 编译器要求将注释 类 包含在运行时类路径中——它们必须在模块信息中声明,这意味着必须使用 implementation
而不是 compileOnly
从 Gradle 访问它们。这似乎是编译器对 JPMS 的支持中的一个漏洞。或者,对于这种奇怪的行为有什么好的解释吗?
这是一个例子。
package com.example;
...
@Retention(RetentionPolicy.SOURCE)
public @interface Example {
...
}
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'
}
ExampleAnnotation
在 Foo.java 中的用法。
package abc;
public class Foo {
@com.example.Example
public void something() {
...
}
}
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;
}
编译项目会产生编译错误,指示 com.example
不可见等
requires
指令对于 任何 依赖项都是强制性的,而不仅仅是运行时依赖项。
与JLS, §7.7.1比较:
7.7.1. Dependences
The
requires
directive specifies the name of a module on which the current module has a dependence.…
The
requires
keyword may be followed by the modifierstatic
. This specifies that the dependence, while mandatory at compile time, is optional at run time.
我不知道使用 requires static my.annotation.proc;
是否可以解决您使用 Gradle 的问题,但这应该是在语言级别处理的方式。