V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
linuxsteam
V2EX  ›  Java

请教关于类加载器报 NoClassDefFoundError 错误的几点疑问(附详细代码)

  •  
  •   linuxsteam · 2022-02-25 17:25:51 +08:00 · 1192 次点击
    这是一个创建于 1034 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题代码

    URL[] urls = new URL[6];
    urls[0] = '/activation-1.1.1.jar'
    urls[1] = '/animal-sniffer-annotations-1.14.jar'
    urls[2] = '/annotations-16.0.2.jar'
    urls[3] = '/antlr-runtime-3.4.jar'
    urls[4] = '/asm-4.2.jar'
    urls[5] = '/cglib-3.1.jar'
    URLClassLoader urlCLassLoader = new URLClassLoader(urls);
    try
    {
        // 将全部存储到 urlclassload 里面
        for (String fullClassName : allFullClassNames)
        {
            if (!"module-info".equals(fullClassName))
            {
                Class<?> clazz = urlCLassLoader.loadClass(fullClassName);
                System.out.println(fullClassName);
            }
        }
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
    

    报错前的日志打印

    https://paste.ubuntu.org.cn/4545513

    net.sf.cglib.transform.AbstractClassTransformer 反编译代码

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by FernFlower decompiler)
    //
    
    package net.sf.cglib.transform;
    
    import org.objectweb.asm.ClassVisitor;
    
    public abstract class AbstractClassTransformer extends ClassTransformer {
        protected AbstractClassTransformer() {
            super(262144);
        }
    
        public void setTarget(ClassVisitor target) {
            this.cv = target;
        }
    }
    

    AppClassLoader 中没有加载 asm-4.2.jar 与 cglib-3.1.jar 中的类,其他的都有加载过了

    上述 jar 包下载地址(无需下载客户端)

    https://www.123pan.com/s/dCH9-LYAAA 提取码:v2ex

    现在针对以上代码小弟有几个问题:

    Class<?> clazz = urlCLassLoader.loadClass("net.sf.cglib.transform.AbstractClassTransformer"); 小弟进入断点后看到这行执行会报错 java.lang.NoClassDefFoundError: org/apache/tools/ant/Task

    这个 NoClassDefFoundError 报错的问题,我在<深入理解 Java 虚拟机:JVM 高级特性与最佳实践(第 3 版)周志明>中找到了原因 大概是 类加载过程解析步骤 出现了 符号引用转为直接引用找不到的问题

    但是还是有以下疑问

    1. org/apache/tools/ant/Task 在类 net.sf.cglib.transform.AbstractClassTransformer 中没有看到任何符号引用,不知道为何会找这个类
    2. 假设:asm-4.2.jar 引用了 cglib-3.1.jar 中的类,那么是不是在加载 asm-4.2.jar 所有类的时候就会报错 NoClassDefFoundError ?
    3 条回复    2022-02-25 17:54:07 +08:00
    Jooooooooo
        1
    Jooooooooo  
       2022-02-25 17:28:08 +08:00
    NoClassDefFoundError 绝大多数都是两个不同的 jar 里有相同的路径, 然后加载类的时候找错了.

    排除一下就行.
    linuxsteam
        2
    linuxsteam  
    OP
       2022-02-25 17:52:29 +08:00
    关于第一个问题
    我又查了下资料
    https://mvnrepository.com/artifact/cglib/cglib/3.3.0
    上述连接中是描述 cglib 依赖于 org.apache.ant » ant 的
    但是该 jar 包 META-INF/中是没有 maven 这个文件夹的。自然我就发现他下面依赖的 org.apache.ant » ant 。。。
    看来我又得研究研究 jar 包的元数据信息了
    linuxsteam
        3
    linuxsteam  
    OP
       2022-02-25 17:54:07 +08:00
    @linuxsteam 但是 org.apache.ant » ant 是可选的。。。我又迷糊了。。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3038 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 14:27 · PVG 22:27 · LAX 06:27 · JFK 09:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.