簡體   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