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

使用URLClassLoader加载JAR类时部分类抛出ClassNotFoundException求助

解决URLClassLoader加载特定类失败的NoClassDefFoundError问题

我之前在Java 8环境下用URLClassLoader加载类的时候确实碰到过类似的问题,尤其是加载com.sun开头的JDK内部类或者第三方依赖类时,容易出现这种NoClassDefFoundError。咱们来拆解下原因和解决办法:

问题原因分析

  • JDK内部API路径缺失:你提到的com.sun.javadoc.Doclet、com.sun.tools.javadoc.Messager这类com.sun开头的类,属于JDK的内部工具类,它们默认存放在JDK目录下的tools.jar中。但Java 8的系统类加载器(你指定的父加载器)默认不会自动加载tools.jar,所以URLClassLoader也无法通过父加载器找到这些类。
  • 第三方依赖未引入:像org.apache.sshd.server.SshServer这类第三方类,说明你的目标JAR依赖了Apache SSHD库,但你只加载了目标JAR,没有把SSHD相关的依赖JAR加入到URLClassLoader的搜索路径中,导致找不到该类。
  • 类名转换错误:如果你的filterJavaClasses方法没有正确把JAR中的路径(比如com/sun/javadoc/Doclet.class)转换成全限定类名(com.sun.javadoc.Doclet),也会导致加载失败。

具体解决方案

1. 加载JDK内部工具类(如com.sun.javadoc.Doclet)

需要手动把JDK的tools.jar加入到URLClassLoader的加载路径中:

// 目标JAR路径
Path jarFilePath = Paths.get("你的目标JAR路径");
// 获取JDK下的tools.jar路径(注意java.home可能指向JRE,需要回退到JDK目录)
Path toolsJarPath = Paths.get(System.getProperty("java.home"))
                        .getParent() // 从JRE目录回到JDK根目录
                        .resolve("lib")
                        .resolve("tools.jar");

URLClassLoader loader = URLClassLoader.newInstance(
    new URL[] { 
        jarFilePath.toUri().toURL(),
        toolsJarPath.toUri().toURL() // 将toolsJar加入加载路径
    }, 
    ClassLoader.getSystemClassLoader()
);

注意:这个方法只适用于Java 8及之前版本,Java 9+已经移除了tools.jar,改用模块化方式访问这些API。

2. 加载第三方依赖类(如org.apache.sshd.server.SshServer)

找到目标JAR依赖的Apache SSHD相关JAR(比如sshd-core.jar),将它们也添加到URLClassLoader的URL数组中,确保所有依赖都被加载:

// 添加SSHD依赖JAR路径
Path sshdCoreJarPath = Paths.get("sshd-core的路径");

URLClassLoader loader = URLClassLoader.newInstance(
    new URL[] { 
        jarFilePath.toUri().toURL(),
        toolsJarPath.toUri().toURL(),
        sshdCoreJarPath.toUri().toURL()
    }, 
    ClassLoader.getSystemClassLoader()
);

3. 验证类名转换逻辑

检查你的filterJavaClasses方法,确保它正确处理了JAR条目:

  • 只保留.class结尾的条目
  • 将路径中的/替换为.
  • 去掉.class后缀,得到正确的全限定类名(比如com/sun/javadoc/Doclet.class → com.sun.javadoc.Doclet)

4. 排查依赖链问题

如果仍然抛出NoClassDefFoundError,可能是目标类依赖的其他类也缺失。可以用javap -c -verbose 目标类.class查看该类的依赖,确保所有依赖类都在加载路径中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:00:54