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 模块化体系中都属于「未命名模块」,写死这个值即可。

相关推荐
摇滚侠4 小时前
《SpringBoot 3:入门与应用实战》第 13 章 整合 MyBatis MyBatis 概述 阅读笔记 37
spring boot·笔记·mybatis
天空属于哈夫克34 小时前
企业微信API:企业微信如何实现自动化运营?
java·自动化·企业微信
用户608186527904 小时前
Avalonia 控件模板实战:从 WPF 迁移自定义 Button 样式的完整指南
后端
lhldsg4 小时前
相册印刷实战指南:从设计规范到系统落地全流程解析
java·小程序·架构·设计规范
草青工作室5 小时前
java-不携带Token也能“打“自己的接口:一个绕开网关鉴权、用 URL 直接调度 SpringMVC 方法的轻量级定时任务方案
java·开发语言
霸道流氓气质5 小时前
Spring AI提示词模板与动态变量替换
java·python·spring
明月_清风5 小时前
GPT-6 Astra 与 AGI 的门槛:我们到底在争论什么?
人工智能·后端·openai
Object_SC5 小时前
java 中的泛型
java
摇滚侠5 小时前
《SpringBoot 3:入门与应用实战》第 13 章 整合 MyBatis 整合 MyBatis 阅读笔记 38
spring boot·笔记·mybatis
jyOverQ5 小时前
RabbitMQ 延迟消息怎么实现?TTL 与死信队列
分布式·后端·rabbitmq·ruby