文章目录

1. 问题描述

首先贴出错误:

NoClassDefFoundError问题排查_jar


本地跑是没有报错的,打包后运行就报错了。

2. 问题排查

可以看到是没有依赖到​​CatalogFactory​​,全局搜索,可以看到该类在flink-table-common-1.13.6.jar这个包。

NoClassDefFoundError问题排查_类加载器_02

3. 问题解决

3.1 解决方案1-添加依赖

查看pom文件,看看有没有依赖,如果没有,添加该依赖。

NoClassDefFoundError问题排查_jar_03


注意:一般到这里就可以解决NoClassDefFoundError这个错误了,下面来看看特殊的情况。

3.2 解决方案2-修复代码

如果依赖了,打包后,运行时还有此错误,就需要解压Jar包,看看/BOOT-INF/lib目录,有依赖没有此jar包,如果没有,就是打包有问题了。

如果有,依然提示此问题,则可能是代码问题了。

NoClassDefFoundError问题排查_jar_04


我们看看代码,代码片段如下:

// 使用URLClassLoader加载本地的jar包
URL url = new File("/temp/test.jar").toURI().toURL();
URLClassLoader classLoader = new URLClassLoader(new URL[]{url});

// 下面是ClassLoader的操作
......

注意:上面是使用​​URLClassLoader​​​只是加载了​​test.jar​​​里面的内容,​​Jar​​​包里面是没有​​CatalogFactory​​,所以就报这个错误了!

该如何解决呢?可以使用​​URLClassLoader​​里面的 “继承”,就是该​​URLClassLoader​​​继承当前环境的​​ClassLoader​​即可,改写完如下:

URL url = new File(jarLocalUrls).toURI().toURL();
URLClassLoader classLoader = new URLClassLoader(
new URL[]{url},
Thread.currentThread().getContextClassLoader()
);

最后,问题就解决了。

4. 排查的方法记录

4.1 查找jar包是否存在、引用某个类的命令

find ./ -name “*.jar” | xargs grep

4.2 查看加载了什么类

java -verbose -jar data-rtc-manage-1.0.0.jar

4.3 Jar包启动流程

参考:《SpringBoot可执行jar包启动原理》

5. 文末

本文记录下这个bug,希望能帮助到大家,谢谢大家的阅读!