调用BukkitLibraryManager报InaccessibleObjectException如何解决
问题描述
程序运行抛出如下异常:
java.lang.reflect.InaccessibleObjectException: Unable to make protected void java.net.URLClassLoader.addURL(java.net.URL) accessible: module java.base does not "opens java.net" to unnamed module @338aec90 at java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) ~[?:?] at java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) ~[?:?] at java.lang.reflect.Method.checkCanSetAccessible(Method.java:199) ~[?:?] at java.lang.reflect.Method.setAccessible(Method.java:193) ~[?:?] at net.byteflux.libby.classloader.URLClassLoaderHelper.<init>(URLClassLoaderHelper.java:37) ~[LifeSteal-1.0.jar:?] at net.byteflux.libby.BukkitLibraryManager.<init>(BukkitLibraryManager.java:28) ~[LifeSteal-1.0.jar:?] at in.arcadelabs.lifesteal.handler.DependencyHandler.<init>(DependencyHandler.java:18) ~[LifeSteal-1.0.jar:?] at in.arcadelabs.lifesteal.LifeStealPlugin.onLoad(LifeStealPlugin.java:39) ~[LifeSteal-1.0.jar:?] at org.bukkit.craftbukkit.v1_19_R1.CraftServer.loadPlugins(CraftServer.java:425) ~[purpur-1.19.jar:git-Purpur-1670] at net.minecraft.server.dedicated.DedicatedServer.initServer(DedicatedServer.java:313) ~[purpur-1.19.jar:git-Purpur-1670] at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1137) ~[purpur-1.19.jar:git-Purpur-1670] at net.minecraft.server.MinecraftServer.lambda$spin$1(MinecraftServer.java:307) ~[purpur-1.19.jar:git-Purpur-1670] at java.lang.Thread.run(Thread.java:833) ~[?:?]
触发场景:使用libby依赖管理库,执行LibraryManager libraryManager = new BukkitLibraryManager();代码时抛出上述异常。
问题根因
该异常是Java 9及以上版本引入的JPMS(Java平台模块系统)强封装机制导致的:
- 高版本Java默认禁止未命名模块通过反射访问
java.base核心模块内非公开的类、方法 - 旧版本libby通过反射调用
java.net.URLClassLoader的受保护方法addURL实现运行时依赖加载,触发了模块访问限制 - 从报错栈的服务端版本(Purpur 1.19)可以判断当前运行环境使用Java 17,属于默认开启强封装检查的LTS版本
修复方案
可根据实际场景选择以下任意一种方案修复:
- 方案1:添加JVM启动参数(最快生效,无需修改代码)
在服务端启动命令的java指令后、-jar参数前,添加模块开放参数:
示例修改后的启动命令:--add-opens java.base/java.net=ALL-UNNAMED
如果是在IDE中本地调试,直接在运行配置的VM options项中添加上述参数即可。java --add-opens java.base/java.net=ALL-UNNAMED -Xmx4G -jar purpur-1.19.jar nogui - 方案2:升级libby依赖版本(长期方案,无需修改启动参数)
将项目中引入的libby依赖升级到2.0及以上的稳定版本,新版本libby已经针对Java 17+的模块限制做了适配,对Paper/Purpur等主流服务端提供了无反射的类加载实现,不会再触发该异常。
注意不要使用1.2.0以下的旧版本libby,这类版本没有做高版本Java兼容。
注意:如果同时使用了其他需要反射访问JDK内部API的插件,可能还需要根据报错追加对应模块的
--add-opens参数,本问题只需要开放java.net包的访问即可。
内容的提问来源于stack exchange,提问作者Ixf1nity
相关产品推荐
相关产品推荐

