龙目岛对jdk.compiler内部软件包的访问与Java-16不兼容 [英] Lombok's access to jdk.compiler's internal packages incompatible with 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 iffork
is set totrue
.
这篇关于龙目岛对jdk.compiler内部软件包的访问与Java-16不兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!