繁体   English   中英

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

注释处理器和编译器插件通常定义带有sourceclass保留的注释。 这些注解不会在运行时暴露,因此不需要将它们包含在运行时类路径中; 它们可以通过compileOnly在 Gradle 构建文件中使用。 此外,无需在module-info文件中声明它们的用途。 然而,在存在module-info文件的情况下,Java 编译器要求注释类包含在运行时类路径中——它们必须在模块信息中声明,这意味着它们必须从 Gradle 访问,并使用implementation而不是compileOnly 这似乎是编译器对 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'
}

在 Foo.java 中使用ExampleAnnotation

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. 依赖性

requires指令指定当前模块所依赖的模块的名称。

requires关键字后面可以跟修饰符static 这指定了依赖关系,虽然在编译时是必需的,但在运行时是可选的。

不知道使用是否requires static my.annotation.proc; 用 Gradle 解决了您的问题,但这就是应该在语言级别处理的方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM