You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JNI注入Jar调用方法时出现NoClassDefFoundError问题求助

问题分析

抛出NoClassDefFoundError的核心原因是注入Jar使用的类加载器无法访问到父进程中net.minecraft.client.Minecraft类的类加载器。Java类加载器遵循双亲委派模型,注入操作常用的自定义类加载器(比如URLClassLoader)默认父加载器是系统类加载器,但Minecraft类通常由游戏专属的类加载器(如LaunchClassLoader)加载,不在系统类加载器的搜索路径范围内,导致自定义加载器无法找到该类。

解决方案
  • 将目标类加载器设为自定义加载器的父加载器
    先通过反射获取父进程中加载Minecraft类的类加载器,再以它作为父加载器创建自定义类加载器来加载你的Jar类。示例代码:

    // 获取Minecraft类对应的类加载器
    Class<?> minecraftClass = Class.forName("net.minecraft.client.Minecraft");
    ClassLoader minecraftClassLoader = minecraftClass.getClassLoader();
    
    // 基于该类加载器创建自定义加载器,加载注入Jar
    URL[] jarUrls = new URL[]{new File("your-injected.jar").toURI().toURL()};
    URLClassLoader customLoader = new URLClassLoader(jarUrls, minecraftClassLoader);
    
    // 加载目标类并调用静态方法
    Class<?> yourClass = customLoader.loadClass("your.package.YourClass");
    Method method = yourClass.getMethod("doStuffIdk");
    method.invoke(null);
    
  • 直接向目标类加载器添加Jar路径
    如果有权限操作目标类加载器,可直接将你的Jar路径添加到其搜索路径中,无需创建新加载器。以Minecraft的LaunchClassLoader为例:

    Class<?> launcherClass = Class.forName("net.minecraft.launchwrapper.LaunchClassLoader");
    Method addURLMethod = launcherClass.getDeclaredMethod("addURL", URL.class);
    addURLMethod.setAccessible(true);
    
    // 将Jar路径注入到Minecraft类加载器
    addURLMethod.invoke(minecraftClassLoader, new File("your-injected.jar").toURI().toURL());
    
    // 直接用Minecraft类加载器加载你的类并调用方法
    Class<?> yourClass = minecraftClassLoader.loadClass("your.package.YourClass");
    yourClass.getMethod("doStuffIdk").invoke(null);
    
  • 统一线程上下文类加载器
    调用静态方法前,将当前线程的上下文类加载器设置为Minecraft的类加载器,避免部分场景下的类加载路径不一致问题:

    Thread.currentThread().setContextClassLoader(minecraftClassLoader);
    

内容的提问来源于stack exchange,提问作者Derek Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:10:24