Nacos 2.x.x版本不适用JDK17的处理方式

由于nacos使用了反射,但是高版本 JDK(Java9+)引入了Java 模块化机制(JPMS),做了严格的反射权限控制,而 Nacos 2.x.x 底层依赖的 Tomcat、SpringBoot 组件还沿用了 JDK8 的反射写法,在高版本 JDK 中会触发权限拦截,直接导致启动失败。

报错信息:Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field static final boolean java.io.FileSystem.useCanonCaches accessible: module java.base does not "opens java.io" to unnamed module @2f7a2457

解决方案包括:

方案一:降级 JDK 版本到 JDK8

最简单粗暴,但是如果已经使用了更高版本JDK切换比较麻烦则不推荐。

方案二:改用Nacos 3.X.X版本

Nacos 3.x.x 需要64 bit JDK 17+,新版本跟老版本有些区别,如果仅用于学习可以使用,生产上需要另外考虑适配性。

方案三:不改 JDK 版本,修改启动脚本添加兼容参数

以Nacos 2.5.2 的windows启动cmd文件为例,添加使用反射访问JDK的模块的权限的参数,效果如下:

在set NACOS_OPTS 前面,添加如下参数

bash 复制代码
rem ========== Java 17+ module opens for Tomcat 9.0.83+ ===============
set "JAVA_OPT=%JAVA_OPT% --add-opens java.base/java.io=ALL-UNNAMED"
set "JAVA_OPT=%JAVA_OPT% --add-opens java.base/java.lang=ALL-UNNAMED"
set "JAVA_OPT=%JAVA_OPT% --add-opens java.base/java.util=ALL-UNNAMED"
set "JAVA_OPT=%JAVA_OPT% --add-opens java.base/sun.nio.ch=ALL-UNNAMED"
rem ====================================================================

在最后的启动命令里,添加上刚刚添加的参数,在"%JAVA%"后面添加%JAVA_OPT%,不用添加双引号 。

bash 复制代码
set COMMAND="%JAVA%" %JAVA_OPT% %NACOS_JVM_OPTS% %NACOS_OPTS% %NACOS_CONFIG_OPTS% %NACOS_LOG4J_OPTS% nacos.nacos %*

保存后正常启动即可。其他版本的启动文件可能略有区别,视情况修改。

前面加的--add-opens 是JVM 核心参数,作用是「开放模块权限 」,允许指定模块的指定包,对「未命名模块」开放反射访问权限(包括私有字段 / 私有方法)

ALL-UNNAMED :代表「所有未命名模块」,Nacos、Tomcat、SpringBoot 这些应用程序,在 JDK 模块化体系中都属于「未命名模块」,写死这个值即可。

相关推荐
森林猿17 小时前
java-modbus-读取-modbus4j
java·网络·python
tobias.b17 小时前
计算机基础知识-数据结构
java·数据结构·考研
reembarkation17 小时前
光标在a-select,鼠标已经移出,下拉框跟随页面滚动
java·数据库·sql
愣头不青17 小时前
617.合并二叉树
java·算法
星轨zb17 小时前
通过实际demo掌握SpringSecurity+MP中的基本框架搭建
数据库·spring boot·spring security·mp
刀法如飞17 小时前
AI编程时代,为什么35岁以上程序员会更吃香?
人工智能·后端·ai编程
小码哥_常17 小时前
Spring Boot 遇上 HMAC-SHA256,API 安全大升级!
后端
小码哥_常18 小时前
10分钟极速掌握!SpringBoot+Vue3整合SSE实现实时消息推送
后端
麦麦鸡腿堡18 小时前
JavaWeb_请求参数,设置响应数据,分层解耦
java·开发语言·前端
大黄说说19 小时前
深入 Go 语言 GMP 调度模型:高并发的秘密武器
后端