龙目岛对jdk.compiler内部软件包的访问与Java-16不兼容 [英] Lombok's access to jdk.compiler's internal packages incompatible with Java-16

查看:202
本文介绍了龙目岛对jdk.compiler内部软件包的访问与Java-16不兼容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Simply upgrading one of my projects from Java-15 to 16 (using the latest build here). On compiling the project which uses lombok such as:

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

我有点被堆栈跟踪卡住了

I am kind of stuck with the stack trace

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

Now, at least as I thought I knew a hack to get this resolved, but even on trying the following configuration on 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>

有人能解决这个问题吗?

Has anyone been able to resolve or get away with this?

编辑 :链接,由

Edit: The link, provided by Jorn in comments, does relate to the same problem on GitHub, but the solutions proposed still doesn't really work. Such that I have added the following args as well:

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

推荐答案

更新:

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

在同一线程中,维护者之一还:

In the same thread, one of the maintainers also writes:

我们有一些鲜为人知的漏洞,可以用来弥合一些差距.同时,我们将开始在gradle和maven插件上进行工作,这将是一个长期的解决方案.

We have some less well known loopholes we can use to bridge a few gaps. We'll start work on gradle and maven plugins in the mean time, which will be a long-term fix.


您在最新的JDK-16版本中看到的异常是由于 JEP 396:强烈封装了JDK内部默认情况下.Lombok正在通​​过反射访问内部JDK API,在以前的Java版本中,这将导致警告消息,而现在却导致硬错误.


The exception you are seeing with the latest JDK-16 build is because of JEP 396: Strongly Encapsulate JDK Internals by Default. Lombok is accessing an internal JDK API with reflection, and where in previous Java versions this would result in a warning message, it now results in a hard error.

通常,在运行Java时,可以通过传递-add-opens =< module>/< package> =<访问模块> 来显式打开内部JDK软件包以进行反射.运行 java 时将伪指令作为VM参数.在这种情况下,这些指令将需要传递给调用 javac 时运行的 java 进程.这可以通过在传递给 javac 的选项之前加上 -J 来实现,该选项会将其传递给底层JVM.

In general, it is possible to explicitly open internal JDK packages for reflection when running java by passing --add-opens=<module>/<package>=<accessing module> directives as VM arguments when running java. In this case these directives would need to be passed to the java process that runs when invoking javac. This can be done by prefixing the option passed to javac with -J, which will instead pass it to the underlying JVM.

使用Maven,我可以使其与以下编译器插件配置一起使用:

Using Maven, I was able to make it work with the following compiler plugin config:

<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> 元素传递所需选项的地方.

Where the needed options are passed using <compilerArgs> elements in the configuration.

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

Note that I added -J in front of the options in order to pass them to the JVM running javac, instead of javac options.

在问题中列出的-add-opens 指令之上,还有一个附加指令:

On top of the --add-opens directives listed in the question, an additional:

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

也需要.

< fork> true</fork> ,因为否则会忽略 -J 选项(根据 mvn clean install的输出判断-X ).查看Maven文档,使用< compilerArgs> :

<fork>true</fork> was also needed since otherwise the -J options were being ignored (judging from the output of mvn clean install -X). Looking at the Maven docs, setting fork to true seems to be needed any time when using <compilerArgs>:

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

< compilerArgs> 设置将 fork 设置为 true 时要传递给编译器的参数.

<compilerArgs> Sets the arguments to be passed to the compiler if fork is set to true.

这篇关于龙目岛对jdk.compiler内部软件包的访问与Java-16不兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆