46

只需将我的一个项目从 Java-15 升级到 16(在此处使用最新版本)。在编译使用 lombok 的项目时,例如:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.16</version>
</dependency>

我有点卡在堆栈跟踪中

Caused by: java.lang.IllegalAccessError: class lombok.javac.apt.LombokProcessor (in unnamed module @0x4e670245) cannot access class com.sun.tools.javac.processing.JavacProcessingEnvironment (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.processing to unnamed module @0x4e670245
    at lombok.javac.apt.LombokProcessor.getJavacProcessingEnvironment (LombokProcessor.java:433)
    at lombok.javac.apt.LombokProcessor.init (LombokProcessor.java:92)
    at lombok.core.AnnotationProcessor$JavacDescriptor.want (AnnotationProcessor.java:160)
    at lombok.core.AnnotationProcessor.init (AnnotationProcessor.java:213)
    at lombok.launch.AnnotationProcessorHider$AnnotationProcessor.init (AnnotationProcessor.java:64)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.<init> (JavacProcessingEnvironment.java:702)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next (JavacProcessingEnvironment.java:829)

现在,至少我认为我知道解决这个问题的技巧,但即使尝试以下配置maven-compiler-plugin

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
        <source>16</source>
        <target>16</target>
        <!--                    <release>16</release>-->
        <compilerArgs>
            <arg>--enable-preview</arg>
            <arg>-Xlint:all</arg>
            <arg>--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
        </compilerArgs>
        <!--for unmappable characters in classes-->
        <encoding>UTF-8</encoding>
        <showDeprecation>true</showDeprecation>
        <showWarnings>true</showWarnings>
        <!--for lombok annotations to resolve-->
        <!--contradictory to maven, intelliJ fails with this-->
        <annotationProcessorPaths>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.16</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

有没有人能够解决或摆脱这个?

编辑 Jorn 在评论中提供的链接确实与 GitHub 上的相同问题有关,但提出的解决方案仍然不起作用。这样我也添加了以下参数:

<arg>--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
4

7 回答 7

69

更新

Lombok v1.18.20 开箱即用支持 JDK 16

在同一个线程中,其中一位维护者还写道

我们有一些鲜为人知的漏洞可以用来弥补一些差距。与此同时,我们将开始研究 gradle 和 maven 插件,这将是一个长期的修复。


原文

您在最新的 JDK-16 构建中看到的异常是因为JEP 396: Strongly Encapsulate JDK Internals by Default。Lombok 正在使用反射访问内部 JDK API,在以前的 Java 版本中,这会导致警告消息,现在会导致硬错误。

通常,可以在运行 java 时显式打开内部 JDK 包进行反射,方法是在运行时将--add-opens=<module>/<package>=<accessing module>指令作为 VM 参数传递java。在这种情况下,这些指令需要传递给java调用时运行的进程javac。这可以通过为传递给的选项加上前缀javacwith来完成-J,而后者会将其传递给底层 JVM。

使用 Maven,我能够使其与以下编译器插件配置一起工作:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
        <source>16</source>
        <target>16</target>
        <!--                    <release>16</release>-->
        <fork>true</fork>
        <compilerArgs>
            <arg>--enable-preview</arg>
            <arg>-Xlint:all</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED</arg>
        </compilerArgs>
        <!--for unmappable characters in classes-->
        <encoding>UTF-8</encoding>
        <showDeprecation>true</showDeprecation>
        <showWarnings>true</showWarnings>
        <!--for lombok annotations to resolve-->
        <!--contradictory to maven, intelliJ fails with this-->
        <annotationProcessorPaths>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.16</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

<compilerArgs>使用配置中的元素传递所需的选项。

请注意,我-J在选项前面添加了选项,以便将它们传递给正在运行的 JVM javac,而不是javac选项。

--add-opens除了问题中列出的指令之外,还有一个:

-J--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED

也需要。

<fork>true</fork>也需要,否则-J选项将被忽略(从 的输出判断mvn clean install -X)。查看 Maven 文档,使用时似乎随时需要设置fork为:true<compilerArgs>

https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#compilerArgs

<compilerArgs>fork如果设置为 ,则设置要传递给编译器的参数true

于 2020-12-20T16:23:15.923 回答
7

升级 lombok 版本1.18.20为我修复它。因此,如果您可以升级 lombok,我建议您这样做。

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
</dependency>
于 2021-11-02T12:02:42.920 回答
3

帮助可能进入该主题的 Gradle 用户。

对于使用Gradle, 要正确配置 Lombok的用户,请在文件中使用compileOnly和。annotationProcessor build.gradle

// Lombok
compileOnly 'org.projectlombok:lombok:1.18.20'
annotationProcessor 'org.projectlombok:lombok:1.18.20'

如果test dependencies您也在那里使用 Lombok,也是如此:

testCompileOnly 'org.projectlombok:lombok:1.18.20'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'

此外,如果您想显式生成字节码目标JDK 16,请使用:

sourceCompatibility = '16'
targetCompatibility = '16'

Source:
设置 Lombok 和 Gradle
Gradle sourceCompatibility 和 targetCompatibility

于 2021-07-10T01:20:04.103 回答
2

对于那些使用 Java 11 或任何与最新版本不同的版本的人,请记住 IntelliJ 可以使用其自己的与 JDK 16/17 挂钩的 Maven 版本,从而在mvn clean install从 IntelliJ 终端执行时导致上述错误。

要检查实际使用的 JDK,请mvn --version在终端中输入,您可能会像我一样感到惊讶(我什至不知道我有 JDK 17):

Maven home: /usr/local/Cellar/maven/3.8.4/libexec
Java version: 17.0.1, vendor: Homebrew, runtime: /usr/local/Cellar/openjdk/17.0.1_1/libexec/openjdk.jdk/Contents/Home
Default locale: en_BG, platform encoding: UTF-8
OS name: "mac os x", version: "11.3.1", arch: "x86_64", family: "mac"

同时,我在检查java --version.

这里的解决方案是mvn clean install通过右侧 Maven 选项卡中的 Maven Goal 按钮执行:

在此处输入图像描述

它正确使用了 JDK 11,也可以通过mvn --version.

于 2022-01-31T11:51:16.390 回答
1

如果你使用macos和jenv,出现这个问题的原因是环境变量JAVA_HOME没有激活,只需执行以下操作:</p>

jenv enable-plugin export

然后重新打开一个终端会话并输入echo $JAVA_HOME

于 2021-12-30T12:38:29.943 回答
0

您需要更改您的 sdk 版本。

如果您使用 IntelliJ IDEA 文件>项目结构并从左侧选择“项目”选项卡。项目 SDK 应该是 1.8 或您在项目中使用的任何版本。Java 版本 16.0.1 不支持访问此版本的 lombok

于 2021-08-27T12:02:08.013 回答
0

我发现是设置我的 JAVA_HOME 变量。如果你不知道那是什么,你可以运行这个命令来找到它。

java -XshowSettings:properties -version 2>&1 > /dev/null | grep 'java.home'

并将 RC 文件中的值设置为 JAVA_HOME。

于 2022-01-06T18:39:41.783 回答