问题也发在悬赏板块了(80金粒),如果有点子也可以来下面回复:
https://www.mcbbs.net/forum.php?mod=viewthread&tid=1140460
最近想写个spigot的classTransformer ASM,但所有java agent内容都需要JDK的 sun.tools.VirtualMachine 也就是那个tools.jar库作为依赖。
我自己的插件依赖它没什么问题,但运行起来就会提示 spigot核心 抛出 ClassNotFoundExcpetion: VirtualMachine , 也就是 sun.tools 不存在。
于是我就怀疑我是不是没装好 JDK, 检查了下环境变量 CLASSPATH 和 %JAVA_HOME% 都直接指向 C:/ProgramFile/Java/jdk1.8.0_131/bin 没什么问题。
spigot的java路径也是 %JAVA_HOME% , 也就是 JDK,但还是抛 ClassNotFoundExcpetion。太奇怪了
命令行的测试返回如下,即便直接运行JDK包里的 java.exe -version 也是提示下面三行,不知道能不能在这里区分 JRE 还是 JDK复制代码(后来换了1.8.0_202 jdk也是依然不行)
有没有大佬曾经尝试过让 spigot 在 JDK 环境中运行的?
或者有没有能让自己plugin正确调用JDK sun 包的方式? 万分感谢
StackTrace Detail:
复制代码
https://www.mcbbs.net/forum.php?mod=viewthread&tid=1140460
最近想写个spigot的classTransformer ASM,但所有java agent内容都需要JDK的 sun.tools.VirtualMachine 也就是那个tools.jar库作为依赖。
我自己的插件依赖它没什么问题,但运行起来就会提示 spigot核心 抛出 ClassNotFoundExcpetion: VirtualMachine , 也就是 sun.tools 不存在。
于是我就怀疑我是不是没装好 JDK, 检查了下环境变量 CLASSPATH 和 %JAVA_HOME% 都直接指向 C:/ProgramFile/Java/jdk1.8.0_131/bin 没什么问题。
spigot的java路径也是 %JAVA_HOME% , 也就是 JDK,但还是抛 ClassNotFoundExcpetion。太奇怪了
命令行的测试返回如下,即便直接运行JDK包里的 java.exe -version 也是提示下面三行,不知道能不能在这里区分 JRE 还是 JDK
- C:\Users\Administrator>java -version
- java version "1.8.0_131"
- Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
- Java HotSpot(TM) 64-Bit Server VM (build 23.131-b11, mixed mode)
有没有大佬曾经尝试过让 spigot 在 JDK 环境中运行的?
或者有没有能让自己plugin正确调用JDK sun 包的方式? 万分感谢
- java.lang.NoClassDefFoundError: com/sun/tools/attach/VirtualMachine
- at com.test.MyCustomPlugin.attachAgent(MyCustomPlugin.java:79) ~[?:?]
- at com.test.MyCustomPlugin.onEnable(MyCustomPlugin.java:39) ~[?:?]
- at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:263) ~[spigot-1.16.3.jar]
- at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:351) ~[spigot-1.16.3.jar]
- ...
- Caused by: java.lang.ClassNotFoundException: com.sun.tools.attach.VirtualMachine
- at java.net.URLClassLoader.findClass(Unknown Source) ~[?:1.8.0_131]
- at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:167) ~[spigot-1.16.3.jar]
- at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_131]
- ...
既然有依赖为什么不直接打包进自己的jar里面呢?加个包前缀避免冲突即可
本帖最后由 inuyasha01 于 2020-12-2 15:08 编辑
早上尝试了下这个方式,但紧接着提示是 AttachNotSupportedException: no providers installed
参考这里的答案:https://www.chenjianjx.com/com-s ... roviders-installed/
他的说法还是:复制代码所以估计不单是 tools.jar的问题,它可能还需要jdk的更多内容,所以,感觉还是spigot没运行在JDK里。。
StackTrace:
复制代码
暮色胡萝卜 发表于 2020-12-2 14:47
既然有依赖为什么不直接打包进自己的jar里面呢?加个包前缀避免冲突即可
早上尝试了下这个方式,但紧接着提示是 AttachNotSupportedException: no providers installed
参考这里的答案:https://www.chenjianjx.com/com-s ... roviders-installed/
他的说法还是:
- 1. 没有使用sun jdk
- 2. 使用了sun jdk,并且JAVA_HOME指向了这个jdk,但是path下的"java"命令不是这个jdk里面的java,而是操作系统默认安装的jre下的,如c:\Program Files\java\….
StackTrace:
- [08:18:34] [Server thread/WARN]: com.test.lib.com.sun.tools.attach.AttachNotSupportedException: no providers installed
- [08:18:34] [Server thread/WARN]: at com.test.lib.com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:48)
- [08:18:34] [Server thread/WARN]: at com.test.MyCustomPlugin.attachAgent(MyCustomPlugin.java:88)
- [08:18:34] [Server thread/WARN]: at com.test.MyCustomPlugin.onEnable(MyCustomPlugin.java:40)
- [08:18:34] [Server thread/WARN]: at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:263)
- [08:18:34] [Server thread/WARN]: at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:351)
- [08:18:34] [Server thread/WARN]: at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:480)
- [08:18:34] [Server thread/WARN]: at org.bukkit.craftbukkit.v1_16_R2.CraftServer.enablePlugin(CraftServer.java:494)
- [08:18:34] [Server thread/WARN]: at org.bukkit.craftbukkit.v1_16_R2.CraftServer.enablePlugins(CraftServer.java:408)
- [08:18:34] [Server thread/WARN]: at net.minecraft.server.v1_16_R2.MinecraftServer.loadWorld(MinecraftServer.java:435)
- [08:18:34] [Server thread/WARN]: at net.minecraft.server.v1_16_R2.DedicatedServer.init(DedicatedServer.java:216)
- [08:18:34] [Server thread/WARN]: at net.minecraft.server.v1_16_R2.MinecraftServer.w(MinecraftServer.java:808)
- [08:18:34] [Server thread/WARN]: at net.minecraft.server.v1_16_R2.MinecraftServer.lambda$0(MinecraftServer.java:164)
- [08:18:34] [Server thread/WARN]: at java.lang.Thread.run(Thread.java:748)
jre的确不包含attach.so
本帖最后由 inuyasha01 于 2020-12-2 17:34 编辑
哦哦 查了一下这个 libattach.so 在 windows系统中对应的是 attach.dll
不过这边已经加载了,用的 System.loadLibrary("attach");
但问题也还是存在,就有点奇怪。估计是 javadoc对 AttachNotSupportedException的描述是 a compatible AttachProvider does not exist.
我再找找解决办法。。。
暮色胡萝卜 发表于 2020-12-2 15:17
jre的确不包含attach.so
哦哦 查了一下这个 libattach.so 在 windows系统中对应的是 attach.dll
不过这边已经加载了,用的 System.loadLibrary("attach");
但问题也还是存在,就有点奇怪。估计是 javadoc对 AttachNotSupportedException的描述是 a compatible AttachProvider does not exist.
我再找找解决办法。。。
本帖最后由 inuyasha01 于 2020-12-3 18:11 编辑
今天尝试另new 个URLClassLoader去加载tools.jar,其结果是所有VM attach, detach 的ClassTransform相关指令运行都十分顺利。功能全部实现。
复制代码
实现参考: https://stackoverflow.com/questi ... runtime/60775#60775
但一到插件重载,或者服务器关闭的时候,就会抛出,额,已经不是抛出了。是服务器VM宕机,dump EXCEPTION_ACCESS_VIOLATION错误 和 hs_err_pid 报告...(https://paste.ubuntu.com/p/KSGBjzZ8jn/)
特意去查了下,我这边Win10-x64系统JDK8u202,正好有个对应的JVM官方BUG。。
https://bugs.openjdk.java.net/browse/JDK-8241358
不知道是不是这个影响的,但觉得还是代码问题。不应该通过URLClassLoader去动态加载 jar,感觉挺危险的
暮色胡萝卜 发表于 2020-12-2 15:17
jre的确不包含attach.so
今天尝试另new 个URLClassLoader去加载tools.jar,其结果是所有VM attach, detach 的ClassTransform相关指令运行都十分顺利。功能全部实现。
- File getJar = new File(folderLibsPath + File.separator + "tools.jar");
- URL jarUrl = getJar.toURI().toURL();
- Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
- method.setAccessible(true);
- method.invoke(classLoaderExt, jarUrl);
实现参考: https://stackoverflow.com/questi ... runtime/60775#60775
但一到插件重载,或者服务器关闭的时候,就会抛出,额,已经不是抛出了。是服务器VM宕机,dump EXCEPTION_ACCESS_VIOLATION错误 和 hs_err_pid 报告...(https://paste.ubuntu.com/p/KSGBjzZ8jn/)
特意去查了下,我这边Win10-x64系统JDK8u202,正好有个对应的JVM官方BUG。。
https://bugs.openjdk.java.net/browse/JDK-8241358
不知道是不是这个影响的,但觉得还是代码问题。不应该通过URLClassLoader去动态加载 jar,感觉挺危险的
本帖最后由 inuyasha01 于 2020-12-3 18:15 编辑
所以想了想,唯一的解决办法是不是只有在插件里直接内置libs了,现在我对这个还不太理解。
在编译后,我把tools.jar的全部class添加进了插件的jar中,运行后的确不会出现ClassNotFoundException了,但还是会出现3楼中的
AttachNotSupportedException: no providers installed (此时我已经能确认attach.dll被成功加载了,但还是这个错误)
。。
虽然楼上的方法可以实现VM的全部transformation功能,但那个关服即崩溃的BUG的确很费解。此外重载插件也会提示java.lang.IllegalStateException: JavaPlugin requires org.bukkit.plugin.java.PluginClassLoader
我总觉得我山穷水尽了 (这是不是spigot自己的ClassLoader的问题啊。。)
暮色胡萝卜 发表于 2020-12-2 15:17
jre的确不包含attach.so
所以想了想,唯一的解决办法是不是只有在插件里直接内置libs了,现在我对这个还不太理解。
在编译后,我把tools.jar的全部class添加进了插件的jar中,运行后的确不会出现ClassNotFoundException了,但还是会出现3楼中的
AttachNotSupportedException: no providers installed (此时我已经能确认attach.dll被成功加载了,但还是这个错误)
。。
虽然楼上的方法可以实现VM的全部transformation功能,但那个关服即崩溃的BUG的确很费解。此外重载插件也会提示java.lang.IllegalStateException: JavaPlugin requires org.bukkit.plugin.java.PluginClassLoader
我总觉得我山穷水尽了 (这是不是spigot自己的ClassLoader的问题啊。。)
本帖最后由 1850343382 于 2020-12-3 20:42 编辑
我也过这类需求,但是我没有你的问题,我把tools.jar注入到了classloader后就可以正常使用了,很少上论坛,你可以加我qq: 1850343382
我也过这类需求,但是我没有你的问题,我把tools.jar注入到了classloader后就可以正常使用了,很少上论坛,你可以加我qq: 1850343382
谢谢分享66666666
本帖最后由 inuyasha01 于 2020-12-4 16:47 编辑
已解决!!
已解决!!
感谢@1850343382 大佬的共同讨论,下午把问题解决了。6楼的代码原本没问题,只是选错了ClassLoader,spigot自己实现了自己的PluginClassLoader继承于URLClassLoader,6楼开始是直接把jar加载到了SystemClassLoader中,后来换成this的PluginClassLoader,问题解决了