如何解决 Java 9 上的 InaccessibleObjectException ("Unable to make {member} accessible: module {A} does not 'opens {package}' to {B}")?
How to solve InaccessibleObjectException ("Unable to make {member} accessible: module {A} does not 'opens {package}' to {B}") on Java 9?
当 运行在 Java 9 上运行应用程序时,会在多种情况下发生此异常。
某些库和框架(Spring、Hibernate、JAXB)特别容易出现这种情况。
这是来自 Javassist 的示例:
java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @1941a8ff
at java.base/jdk.internal.reflect.Reflection.throwInaccessibleObjectException(Reflection.java:427)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:201)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:192)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:186)
at javassist.util.proxy.SecurityActions.setAccessible(SecurityActions.java:102)
at javassist.util.proxy.FactoryHelper.toClass2(FactoryHelper.java:180)
at javassist.util.proxy.FactoryHelper.toClass(FactoryHelper.java:163)
at javassist.util.proxy.ProxyFactory.createClass3(ProxyFactory.java:501)
at javassist.util.proxy.ProxyFactory.createClass2(ProxyFactory.java:486)
at javassist.util.proxy.ProxyFactory.createClass1(ProxyFactory.java:422)
at javassist.util.proxy.ProxyFactory.createClass(ProxyFactory.java:394)
消息说:
Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @1941a8ff
如何避免异常并使程序 运行 成功?
异常是由于Java9引入的Java Platform Module System,特别是强封装的实现。
它只允许 access 在某些条件下,最突出的是:
- 类型必须是 public
- 必须导出拥有的包
同样的限制也适用于反射,导致异常的代码试图使用反射。
更准确地说,异常是由对 setAccessible
的调用引起的。
这可以在上面的堆栈跟踪中看到,其中 javassist.util.proxy.SecurityActions
中的相应行如下所示:
static void setAccessible(final AccessibleObject ao,
final boolean accessible) {
if (System.getSecurityManager() == null)
ao.setAccessible(accessible); // <~ Dragons
else {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
ao.setAccessible(accessible); // <~ moar Dragons
return null;
}
});
}
}
为了确保程序 运行 成功,必须说服模块系统允许访问调用 setAccessible
的元素。
所需的所有信息都包含在异常消息中,但有 a number of mechanisms 来实现这一点。
哪一个最好取决于导致它的确切场景。
Unable to make {member} accessible: module {A} does not 'opens {package}' to {B}
到目前为止,最突出的场景是以下两个:
库或框架使用反射调用 JDK 模块。
在这种情况下:
{A}
是一个 Java 模块(前缀为 java.
或 jdk.
)
{member}
和 {package}
是 Java API 的一部分
{B}
是库、框架或应用程序模块;经常 unnamed module @...
基于反射的 library/framework,如 Spring、Hibernate、JAXB,...反射应用程序代码以访问 bean、实体...
在这种情况下:
{A}
是一个应用模块
{member}
和{package}
是应用代码的一部分
{B}
是框架模块或 unnamed module @...
请注意,某些库(例如 JAXB)可能在两个帐户上都失败,因此请仔细查看您所处的场景!
问题中的是案例1.
1。反射调用 JDK
JDK 模块对于应用程序开发人员来说是不可变的,因此我们无法更改它们的属性。
这只剩下一种可能的解决方案:command line flags。
有了它们,就可以打开特定的包进行反思。
所以在像上面这样的情况下(缩短)...
Unable to make java.lang.ClassLoader.defineClass accessible: module java.base does not "opens java.lang" to unnamed module @1941a8ff
...正确的解决方法是按如下方式启动 JVM:
# --add-opens has the following syntax: {A}/{package}={B}
java --add-opens java.base/java.lang=ALL-UNNAMED
如果反射代码在命名模块中,ALL-UNNAMED
可以用它的名字代替。
请注意,有时很难找到一种方法将此标志应用于将实际执行反射代码的 JVM。
如果有问题的代码是项目构建过程的一部分,并且在构建工具生成的 JVM 中执行,这可能会特别困难。
如果要添加的标志太多,您可以考虑使用 encapsulation kill switch --permit-illegal-access
。它将允许 class 路径上的所有代码反映整体命名模块。请注意,此标志 仅适用于 Java 9!
2。对应用程序代码的反思
在这种情况下,您很可能可以编辑使用反射闯入的模块。
(如果不是,那么您实际上就是案例 1。)这意味着命令行标志不是必需的,而是可以使用模块 {A}
的描述符来打开其内部结构。
有多种选择:
- 使用
exports {package}
导出包,这使得它在编译和 运行 时对所有代码可用
- 使用
exports {package} to {B}
将包导出到访问模块,这使得它在编译和 运行 时可用,但仅限于 {B}
- 使用
opens {package}
打开包,这使得它在 运行 时间(有或没有反射)对所有代码可用
- 使用
opens {package} to {B}
将包打开到访问模块,这使得它在 运行 时间可用(有或没有反射)但只对 {B}
- 使用
open module {A} { ... }
打开整个模块,这使得它的所有包在 运行 时间(有或没有反射)对所有代码可用
有关这些方法的更详细讨论和比较,请参阅 this post。
使用 --add-opens 应该被视为一种解决方法。正确的做法是 Spring、Hibernate 和其他进行非法访问的库来解决它们的问题。
这是一个非常具有挑战性的问题;正如其他人所指出的, --add-opens 选项只是一种解决方法。一旦 Java 9 公开可用,解决根本问题的紧迫性只会增加。
我在 Java 9 上测试基于 Hibernate 的应用程序时收到这个确切的 Javassist 错误后发现自己在这个页面上。因为我的目标是支持 Java 7, 8 和 9 在多个平台上,我努力寻找最佳解决方案。 (请注意,Java 7 和 8 JVM 在命令行上看到无法识别的“--add-opens”参数时会立即中止;因此这无法通过对批处理文件、脚本或快捷键。)
如果能从主流库(例如 Spring 和 Hibernate)的作者那里得到官方指导就好了,但是距离 Java 9 当前预计发布还有 100 天,这个建议似乎仍然很难找到。
经过多次实验和测试,我很欣慰地找到了 Hibernate 的解决方案:
- 使用 Hibernate 5.0.0 或更高版本(早期版本无法使用),并且
- 请求构建时字节码增强(使用Gradle、Maven 或Ant 插件)。
这避免了 Hibernate 在运行时执行 Javassist-based class 修改的需要,从而消除了原始 post 中显示的堆栈跟踪。
但是,之后您应该彻底测试您的应用程序。 Hibernate 在构建时应用的字节码更改似乎与在运行时应用的字节码更改不同,导致应用程序行为略有不同。当我启用构建时字节码增强时,我的应用程序中已经成功多年的单元测试突然失败了。 (我不得不追查新的 LazyInitializationExceptions 和其他问题。)而且行为似乎因 Hibernate 的一个版本而异。谨慎行事。
我收到了有关休眠 5 的警告。
Illegal reflective access by javassist.util.proxy.SecurityActions
我将最新的 javassist 库添加到依赖项 gradle:
compile group: 'org.javassist', name: 'javassist', version: '3.22.0-GA'
这解决了我的问题。
将 --illegal-access=warn 和 --add-opens java.base/java.lang=ALL-UNNAMED 添加到您的 eclipse.ini
我在 2021 年使用 openJDK 1.8 和 STS 4 时遇到了同样的问题。
Window => Preferences => Java => Installed JREs.
我使用添加选项添加了一个新的 JRE(如下所述),浏览到 openJdk 文件夹,select 确定。将新的 JDK 设置为默认值。点击应用并关闭。
/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre
它就像一个魅力:)
我按照顶部评论中的步骤进行操作,但在 Add-exports configuration
弹出窗口 window 中,我输入了错误的模块并选择了 opens
复选框而不是 exports
复选框并保存。这解决了我的问题。
将现有的基于JDK1.8的Springboot项目导入到SpringTestSuite4后,遇到了同样的问题。当我在嵌入式 Tomcat 服务器上启动应用程序时,出现此错误
java.lang.reflect.InaccessibleObjectException: Unable to make
protected final java.lang.Class
java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
throws java.lang.ClassFormatError accessible: module java.base does
not "opens java.lang" to unnamed module @140c9f39 %09
我在 Window -> 首选项 -> Java 下的 Installed JRE 部分中将预安装的 JDK1.8 JRE 从我的 PC 添加到 SpringTestSuite4,并将添加的 JRE 设置为默认值。然后我点击应用然后关闭。
对我有用。
对我来说,我只是更改了 spring-boot-starter-web 版本并为我工作
遇到了同样的问题。原因之一可能是使用了错误的 JDK / Project SDK。
解决 Intellij 中的这个问题:
Right Click on the Maven Project -> Open Module Settings -> Project
Settings -> Project -> Select your SDK to already installed JDK 1.8
对我有用!
我在 运行 SornarQube 时遇到了类似的问题,我通过执行以下操作获得了上传声纳报告的解决方法:
现有软件包:Java16.0.2、MacOS (BigSur)
- 已安装sonar_scanner
- 运行 此命令:导出 SONAR_SCANNER_OPTS="--illegal-access=permit"
希望这对遇到同样问题的人有所帮助,s/he 可以试试这个。 :-)
最近的反馈
许多解决此问题的建议都与 vm 启动器选项有关 --illegal-access
。
根据 Oracle 的说法,JEP 403 (link1) and JEP 403 (link2) 已决定 从 JDK 17 及以后 交付,启动器选项 --illegal-access
将停止工作!
Summary Strongly encapsulate all internal elements of the JDK, except
for critical internal APIs such as sun.misc.Unsafe. It will no longer
be possible to relax the strong encapsulation of internal elements via
a single command-line option, as was possible in JDK 9 through JDK 16.
和
With this change, it will no longer be possible for end users to use
the --illegal-access option to enable access to internal elements of
the JDK. (A list of the packages affected is available here.) The
sun.misc and sun.reflect packages will still be exported by the
jdk.unsupported module, and will still be open so that code can access
their non-public elements via reflection. No other JDK packages will
be open in this way.
It will still be possible to use the --add-opens
command-line option, or the Add-Opens
JAR-file manifest attribute, to open specific packages.
因此以下解决方案将继续有效
# --add-opens has the following syntax: {A}/{package}={B}
java --add-opens java.base/java.lang=ALL-UNNAMED
但是 --illegal-access
的解决方案将从 JDK 17
开始停止工作。
添加到您的 JVM 命令行或转到 Eclipse 目录中的 eclipse.ini
文件并添加以下内容:
--add-opens java.base/java.lang=ALL-UNNAMED
Pre Java 17(因为Java 17去掉了这个参数)你还要加上:
--illegal-access=warn
日食中:
Windows -> Preferences -> Java -> Installed JREs
在打开的向导中单击添加、select Standard VM
并单击 Next
,然后浏览到您安装的 Java 程序文件的路径。例如,对我来说是 C:\Program Files\Java\jre1.8.0_301\lib
.
点击完成然后select新添加的JR。
Right-click on your Project -> Build Path -> Configure Build Path
在打开的向导中转到 Libraries
选项卡并单击 Add Library
然后 select JRE System Library
单击下一步。 Select Alternate JRE
然后 select 您之前从下拉列表中添加的 JRE。单击完成。
转到 Order and Export
选项卡和 select 您添加的 JRE,并将其移至导致问题的其他系统库之上。 Select 申请并关闭。大功告成。
仍然可以尝试使用旧的 JKD 版本。
对于 Eclipse,您需要做两件事。前往
Window -> 首选项 -> java -> 编译器
将编译器合规级别设置为特定版本
就我而言,Eclipse 版本设置为 JDK 16 我将其恢复为 1.8,因为我的代码是用 1.8
编写的
Window -> 首选项 -> Java -> 安装的 JRE。
添加JRE安装路径(Select Standard VM)
它对我来说很顺利..
2021年,我使用OpenJDK语言版本16时才出现这个问题。当我降级到较低版本时,它起作用了。我猜这是因为 OpenJDK 做了这个:JEP 396: Strongly Encapsulate JDK Internals by Default
我今天花了很多时间尝试添加 --add-opens JVM 选项。升级到 SpringBoot 2.6.4(如果您正在使用依赖管理,将升级到 spring 框架 5.3.16)解决了这个问题,但没有添加 JVM 选项。
我使用的是 jdk18+,但只想要 jdk8。我从类路径中删除了 18,并为运行良好的应用程序添加了 8。
当 运行在 Java 9 上运行应用程序时,会在多种情况下发生此异常。 某些库和框架(Spring、Hibernate、JAXB)特别容易出现这种情况。 这是来自 Javassist 的示例:
java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @1941a8ff
at java.base/jdk.internal.reflect.Reflection.throwInaccessibleObjectException(Reflection.java:427)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:201)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:192)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:186)
at javassist.util.proxy.SecurityActions.setAccessible(SecurityActions.java:102)
at javassist.util.proxy.FactoryHelper.toClass2(FactoryHelper.java:180)
at javassist.util.proxy.FactoryHelper.toClass(FactoryHelper.java:163)
at javassist.util.proxy.ProxyFactory.createClass3(ProxyFactory.java:501)
at javassist.util.proxy.ProxyFactory.createClass2(ProxyFactory.java:486)
at javassist.util.proxy.ProxyFactory.createClass1(ProxyFactory.java:422)
at javassist.util.proxy.ProxyFactory.createClass(ProxyFactory.java:394)
消息说:
Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @1941a8ff
如何避免异常并使程序 运行 成功?
异常是由于Java9引入的Java Platform Module System,特别是强封装的实现。 它只允许 access 在某些条件下,最突出的是:
- 类型必须是 public
- 必须导出拥有的包
同样的限制也适用于反射,导致异常的代码试图使用反射。
更准确地说,异常是由对 setAccessible
的调用引起的。
这可以在上面的堆栈跟踪中看到,其中 javassist.util.proxy.SecurityActions
中的相应行如下所示:
static void setAccessible(final AccessibleObject ao,
final boolean accessible) {
if (System.getSecurityManager() == null)
ao.setAccessible(accessible); // <~ Dragons
else {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
ao.setAccessible(accessible); // <~ moar Dragons
return null;
}
});
}
}
为了确保程序 运行 成功,必须说服模块系统允许访问调用 setAccessible
的元素。
所需的所有信息都包含在异常消息中,但有 a number of mechanisms 来实现这一点。
哪一个最好取决于导致它的确切场景。
Unable to make {member} accessible: module {A} does not 'opens {package}' to {B}
到目前为止,最突出的场景是以下两个:
库或框架使用反射调用 JDK 模块。 在这种情况下:
{A}
是一个 Java 模块(前缀为java.
或jdk.
){member}
和{package}
是 Java API 的一部分
{B}
是库、框架或应用程序模块;经常unnamed module @...
基于反射的 library/framework,如 Spring、Hibernate、JAXB,...反射应用程序代码以访问 bean、实体... 在这种情况下:
{A}
是一个应用模块{member}
和{package}
是应用代码的一部分{B}
是框架模块或unnamed module @...
请注意,某些库(例如 JAXB)可能在两个帐户上都失败,因此请仔细查看您所处的场景! 问题中的是案例1.
1。反射调用 JDK
JDK 模块对于应用程序开发人员来说是不可变的,因此我们无法更改它们的属性。 这只剩下一种可能的解决方案:command line flags。 有了它们,就可以打开特定的包进行反思。
所以在像上面这样的情况下(缩短)...
Unable to make java.lang.ClassLoader.defineClass accessible: module java.base does not "opens java.lang" to unnamed module @1941a8ff
...正确的解决方法是按如下方式启动 JVM:
# --add-opens has the following syntax: {A}/{package}={B}
java --add-opens java.base/java.lang=ALL-UNNAMED
如果反射代码在命名模块中,ALL-UNNAMED
可以用它的名字代替。
请注意,有时很难找到一种方法将此标志应用于将实际执行反射代码的 JVM。 如果有问题的代码是项目构建过程的一部分,并且在构建工具生成的 JVM 中执行,这可能会特别困难。
如果要添加的标志太多,您可以考虑使用 encapsulation kill switch --permit-illegal-access
。它将允许 class 路径上的所有代码反映整体命名模块。请注意,此标志 仅适用于 Java 9!
2。对应用程序代码的反思
在这种情况下,您很可能可以编辑使用反射闯入的模块。
(如果不是,那么您实际上就是案例 1。)这意味着命令行标志不是必需的,而是可以使用模块 {A}
的描述符来打开其内部结构。
有多种选择:
- 使用
exports {package}
导出包,这使得它在编译和 运行 时对所有代码可用 - 使用
exports {package} to {B}
将包导出到访问模块,这使得它在编译和 运行 时可用,但仅限于{B}
- 使用
opens {package}
打开包,这使得它在 运行 时间(有或没有反射)对所有代码可用 - 使用
opens {package} to {B}
将包打开到访问模块,这使得它在 运行 时间可用(有或没有反射)但只对{B}
- 使用
open module {A} { ... }
打开整个模块,这使得它的所有包在 运行 时间(有或没有反射)对所有代码可用
有关这些方法的更详细讨论和比较,请参阅 this post。
使用 --add-opens 应该被视为一种解决方法。正确的做法是 Spring、Hibernate 和其他进行非法访问的库来解决它们的问题。
这是一个非常具有挑战性的问题;正如其他人所指出的, --add-opens 选项只是一种解决方法。一旦 Java 9 公开可用,解决根本问题的紧迫性只会增加。
我在 Java 9 上测试基于 Hibernate 的应用程序时收到这个确切的 Javassist 错误后发现自己在这个页面上。因为我的目标是支持 Java 7, 8 和 9 在多个平台上,我努力寻找最佳解决方案。 (请注意,Java 7 和 8 JVM 在命令行上看到无法识别的“--add-opens”参数时会立即中止;因此这无法通过对批处理文件、脚本或快捷键。)
如果能从主流库(例如 Spring 和 Hibernate)的作者那里得到官方指导就好了,但是距离 Java 9 当前预计发布还有 100 天,这个建议似乎仍然很难找到。
经过多次实验和测试,我很欣慰地找到了 Hibernate 的解决方案:
- 使用 Hibernate 5.0.0 或更高版本(早期版本无法使用),并且
- 请求构建时字节码增强(使用Gradle、Maven 或Ant 插件)。
这避免了 Hibernate 在运行时执行 Javassist-based class 修改的需要,从而消除了原始 post 中显示的堆栈跟踪。
但是,之后您应该彻底测试您的应用程序。 Hibernate 在构建时应用的字节码更改似乎与在运行时应用的字节码更改不同,导致应用程序行为略有不同。当我启用构建时字节码增强时,我的应用程序中已经成功多年的单元测试突然失败了。 (我不得不追查新的 LazyInitializationExceptions 和其他问题。)而且行为似乎因 Hibernate 的一个版本而异。谨慎行事。
我收到了有关休眠 5 的警告。
Illegal reflective access by javassist.util.proxy.SecurityActions
我将最新的 javassist 库添加到依赖项 gradle:
compile group: 'org.javassist', name: 'javassist', version: '3.22.0-GA'
这解决了我的问题。
将 --illegal-access=warn 和 --add-opens java.base/java.lang=ALL-UNNAMED 添加到您的 eclipse.ini
我在 2021 年使用 openJDK 1.8 和 STS 4 时遇到了同样的问题。
Window => Preferences => Java => Installed JREs.
我使用添加选项添加了一个新的 JRE(如下所述),浏览到 openJdk 文件夹,select 确定。将新的 JDK 设置为默认值。点击应用并关闭。
/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre
它就像一个魅力:)
我按照顶部评论中的步骤进行操作,但在 Add-exports configuration
弹出窗口 window 中,我输入了错误的模块并选择了 opens
复选框而不是 exports
复选框并保存。这解决了我的问题。
将现有的基于JDK1.8的Springboot项目导入到SpringTestSuite4后,遇到了同样的问题。当我在嵌入式 Tomcat 服务器上启动应用程序时,出现此错误
java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @140c9f39 %09
我在 Window -> 首选项 -> Java 下的 Installed JRE 部分中将预安装的 JDK1.8 JRE 从我的 PC 添加到 SpringTestSuite4,并将添加的 JRE 设置为默认值。然后我点击应用然后关闭。
对我有用。
对我来说,我只是更改了 spring-boot-starter-web 版本并为我工作
遇到了同样的问题。原因之一可能是使用了错误的 JDK / Project SDK。
解决 Intellij 中的这个问题:
Right Click on the Maven Project -> Open Module Settings -> Project Settings -> Project -> Select your SDK to already installed JDK 1.8
对我有用!
我在 运行 SornarQube 时遇到了类似的问题,我通过执行以下操作获得了上传声纳报告的解决方法:
现有软件包:Java16.0.2、MacOS (BigSur)
- 已安装sonar_scanner
- 运行 此命令:导出 SONAR_SCANNER_OPTS="--illegal-access=permit"
希望这对遇到同样问题的人有所帮助,s/he 可以试试这个。 :-)
最近的反馈
许多解决此问题的建议都与 vm 启动器选项有关 --illegal-access
。
根据 Oracle 的说法,JEP 403 (link1) and JEP 403 (link2) 已决定 从 JDK 17 及以后 交付,启动器选项 --illegal-access
将停止工作!
Summary Strongly encapsulate all internal elements of the JDK, except for critical internal APIs such as sun.misc.Unsafe. It will no longer be possible to relax the strong encapsulation of internal elements via a single command-line option, as was possible in JDK 9 through JDK 16.
和
With this change, it will no longer be possible for end users to use the --illegal-access option to enable access to internal elements of the JDK. (A list of the packages affected is available here.) The sun.misc and sun.reflect packages will still be exported by the jdk.unsupported module, and will still be open so that code can access their non-public elements via reflection. No other JDK packages will be open in this way.
It will still be possible to use the --add-opens command-line option, or the Add-Opens JAR-file manifest attribute, to open specific packages.
因此以下解决方案将继续有效
# --add-opens has the following syntax: {A}/{package}={B}
java --add-opens java.base/java.lang=ALL-UNNAMED
但是 --illegal-access
的解决方案将从 JDK 17
开始停止工作。
添加到您的 JVM 命令行或转到 Eclipse 目录中的 eclipse.ini
文件并添加以下内容:
--add-opens java.base/java.lang=ALL-UNNAMED
Pre Java 17(因为Java 17去掉了这个参数)你还要加上:
--illegal-access=warn
日食中:
Windows -> Preferences -> Java -> Installed JREs
在打开的向导中单击添加、select Standard VM
并单击 Next
,然后浏览到您安装的 Java 程序文件的路径。例如,对我来说是 C:\Program Files\Java\jre1.8.0_301\lib
.
点击完成然后select新添加的JR。
Right-click on your Project -> Build Path -> Configure Build Path
在打开的向导中转到 Libraries
选项卡并单击 Add Library
然后 select JRE System Library
单击下一步。 Select Alternate JRE
然后 select 您之前从下拉列表中添加的 JRE。单击完成。
转到 Order and Export
选项卡和 select 您添加的 JRE,并将其移至导致问题的其他系统库之上。 Select 申请并关闭。大功告成。
仍然可以尝试使用旧的 JKD 版本。
对于 Eclipse,您需要做两件事。前往
Window -> 首选项 -> java -> 编译器 将编译器合规级别设置为特定版本 就我而言,Eclipse 版本设置为 JDK 16 我将其恢复为 1.8,因为我的代码是用 1.8
编写的Window -> 首选项 -> Java -> 安装的 JRE。 添加JRE安装路径(Select Standard VM)
它对我来说很顺利..
2021年,我使用OpenJDK语言版本16时才出现这个问题。当我降级到较低版本时,它起作用了。我猜这是因为 OpenJDK 做了这个:JEP 396: Strongly Encapsulate JDK Internals by Default
我今天花了很多时间尝试添加 --add-opens JVM 选项。升级到 SpringBoot 2.6.4(如果您正在使用依赖管理,将升级到 spring 框架 5.3.16)解决了这个问题,但没有添加 JVM 选项。
我使用的是 jdk18+,但只想要 jdk8。我从类路径中删除了 18,并为运行良好的应用程序添加了 8。