如何让jmxterm在Java 17中访问sun.tools.jconsole.LocalVirtualMachine?
问题:jmxterm 1.0.4 与 Java 17 兼容故障(无法访问sun.tools.jconsole.LocalVirtualMachine)
问题详情
- 环境:Eclipse Temurin Java 17,jmxterm 1.0.4
- 执行命令:
printf "open 25522\n" | java -jar jmxterm-1.0.4-uber.jar -v verbose - 错误:抛出
IllegalAccessException,根因是Java 17的模块封装机制限制,无法访问jdk.jconsole模块中的sun.tools.jconsole.LocalVirtualMachine内部类 - 已尝试无效的方案:
- 修改pom.xml为maven-compiler-plugin添加
--add-exports参数 - 配置surefire插件的
argLine参数 - 基于Java 17重新构建uber jar,运行时追加
--add-exports参数 - 尝试使用
--add-opens参数 - 将编译source/target设为17
- 添加
--add-modules jdk.jconsole参数
- 修改pom.xml为maven-compiler-plugin添加
- 疑问:是否遗漏关键配置,还是该需求无法实现?
解决方案
1. 传递正确的运行时模块开放参数
Java 17对内部API的限制比旧版本更严格,sun.tools.jconsole.LocalVirtualMachine属于jdk.jconsole模块的非公开类,需要同时开放导出和打开权限给未命名模块(jmxterm属于未命名模块)。运行时必须使用以下完整命令:
printf "open 25522\n" | java --add-exports jdk.jconsole/sun.tools.jconsole=ALL-UNNAMED --add-opens jdk.jconsole/sun.tools.jconsole=ALL-UNNAMED -jar jmxterm-1.0.4-uber.jar -v verbose
注意:ALL-UNNAMED是固定值,代表允许所有未模块化的JAR包访问该内部包。
2. 修正构建阶段的参数配置
如果自行构建jmxterm,需确保编译和测试阶段都正确传递模块权限参数:
maven-compiler-plugin配置
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>17</source> <target>17</target> <compilerArgs> <arg>--add-exports</arg> <arg>jdk.jconsole/sun.tools.jconsole=ALL-UNNAMED</arg> <arg>--add-opens</arg> <arg>jdk.jconsole/sun.tools.jconsole=ALL-UNNAMED</arg> </compilerArgs> </configuration> </plugin>
maven-surefire-plugin配置
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.2.2</version> <configuration> <argLine> --add-exports jdk.jconsole/sun.tools.jconsole=ALL-UNNAMED --add-opens jdk.jconsole/sun.tools.jconsole=ALL-UNNAMED </argLine> </configuration> </plugin>
完成配置后执行mvn clean package重新构建,确保无编译错误。
3. 升级jmxterm到最新版本
jmxterm 1.0.4发布于2020年,未针对Java 17的模块系统做适配。升级到最新稳定版(如1.0.7及以上),新版本通常已修复Java 17兼容问题,无需手动添加模块参数。
4. 替代工具方案
如果jmxterm的兼容问题无法解决,可使用JDK自带工具满足需求:
- jconsole:图形化JMX客户端,直接输入
jconsole localhost:25522连接目标进程 - jcmd:命令行工具,通过
jcmd <目标进程PID> JMX.check查看JMX状态,或用jcmd <PID> help获取可用命令列表
5. 验证目标JVM的JMX配置
确保端口25522对应的目标JVM已开启远程JMX访问,启动参数需包含:
-Dcom.sun.management.jmxremote.port=25522 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
(生产环境建议启用认证和SSL加密)
内容的提问来源于stack exchange,提问作者gla3dr
相关产品推荐
相关产品推荐

