记一次NoClassDefFoundError

Image by huoadg5888 from Pixabay

前言

今天跑新项目,发现新项目中的某个接口报NoClassDefFoundError,该接口调用了某个类的静态方法,而该静态方法的主要作用是获取远程配置信息;错误信息是:java.lang.NoClassDefFoundError: Could not initialize class 某类;第一眼发现这个错误还以为是这个类没导入,但是在编译文件下找到了该文件是存在的;

解决

  1. 通过参考中的几篇的文章中,发现是静态方法中的某个问题,获取远程配置,但是远程并没有配置;最后在配置中心进行配置就可以了;
  2. 可以将静态加载进行判断,不出错就行了;

例子

1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

public class TestNoClassDefFoundError {
    public static void main(String[] args) throws InterruptedException {
        TestNoClassDefFoundError sample = new TestNoClassDefFoundError();
        sample.getClassWithInitErrors();
    }

    private void getClassWithInitErrors() throws InterruptedException {
        System.out.println("第一次new");
        Thread.sleep(500);
        try {
            //第一次new ClassWithInitErrors类,JVM会加载该类,初始化该类的静态变量或执行静态块
            new ClassWithInitErrors();
        } catch (Throwable t) {
            //因为初始化静态变量失败,所以加载类失败。
            t.printStackTrace();
        }

        Thread.sleep(500);
        System.out.println("-----------------------------------------------------");
        System.out.println("第二次new");
        Thread.sleep(500);
        try {
            //第二次new ClassWithInitErrors类,JVM不会再加载该类,而是抛出NoClassDefFoundError异常
            new ClassWithInitErrors();
        } catch (Throwable t) {
            t.printStackTrace();
        }
        Thread.sleep(500);
        System.out.println("-----------------------------------------------------");
        System.out.println("第三次new");
        Thread.sleep(500);
        try {
            //第三次new ClassWithInitErrors类,JVM不会再加载该类,而是抛出NoClassDefFoundError异常
            new ClassWithInitErrors();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}

class ClassWithInitErrors {
    static int data = 1 / 0;
}

2

项目中大概就是这样的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

public class MapUtil {
    private static Map<String,String> keyMap;
    static {
        keyMap.put("1","2");
    }
    static void reload(){
        keyMap=new HashMap<>();
    }

    public static String get(String key){
        if(keyMap==null){
            reload();
        }
        return keyMap.get(key);
    }
}

在首次调用该类的get()方法时,静态模块会进行输入,会抛出java.lang.NullPointerException: null,第二次调用时会出现java.lang.NoClassDefFoundError: Could not initialize class com.example.demo.util.MapUtil

疑问

例二的例子在第一次调用时会报错,而我在项目中却没有报错误,也许是在哪里被拦截了吧;

最后

  1. 虽然问题不大,但是第一次遇到这样的问题,还是记录一下,增强记忆;
  2. 该问题涉及的知识点比较多,后面得花时间整理整理。

参考:

  1. java.lang.NoClassDefFoundError错误
  2. java.lang.NoClassDefFoundError: Could not initialize class xxx 原因
  3. Tomcat java.lang.NoClassDefFoundError: Could not initialize class
  4. 怎么解决java.lang.NoClassDefFoundError错误
  5. java.lang.NoClassDefFoundError
坚持原创技术分享,您的支持将鼓励我继续创作!