avatar

目录
NoClassDefFoundError

NoClassDefFoundError 错误说明

Code
1
2
3
4
5
Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.SolrUtils

class类对象没有加载成功,在程序调用该类static方法的时候,因为没有这个类对象 所以找不到 ,会报异常
错误原因:
在 类加载 的工程中,有异常抛出 导致 类加载 未完成,class 类对象没有生成

NoClassDefFoundError错误的发生,是因为Java虚拟机在编译时能找到合适的类,而在运行时不能找到合适的类导致的错误。

测试demo

Code
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
46
47
48
49
50
51
52
53
54
55
56
57

/**
* solr solrUtils
* Created by liuyudut.liu on 17-10-10.
*/

public class SolrUtils {
private final static Logger logger = LoggerFactory.getLogger(SolrUtils.class);

private static CloudSolrClient cloudSolrClient ;

static{
String zkHost = "asdfasdfsaf";
try {
logger.info("solrCloud 开始连接------------------------------------------12345---------------");
cloudSolrClient = new CloudSolrClient.Builder().withZkHost(zkHost).build();
// cloudSolrClient = new HttpSolrClient.Builder().withBaseSolrUrl(solrUrl).build();//单个solr url
logger.info("solrCloud 加载结束------------------------------------------12345---------------");
test();
}catch (Exception e){
throw new ValidationRuntimeException("solr zkHost 有误 连接失败",e);
}
}


public static SolrClient test() {
throw new RuntimeException("qwwweweee");
}
public static SolrClient getSolrClient() {
return cloudSolrClient;
}

private SolrUtils() {}

/**
* 更新CloudSolrClient变量
* @param zookhost
*/
public static void updateSolrClient(String zookhost){
logger.info("updateSolrClient 开始更新------------------------------------------12345---------------");

if(Strings.isNullOrEmpty(zookhost)){
return;
}
CloudSolrClient temp = null;
try {
temp = new CloudSolrClient.Builder().withZkHost(zookhost).build();
}catch (Exception e){
throw new ValidationRuntimeException("solr zkHost 有误 连接失败",e);
}
if(temp != null){
synchronized (SolrUtils.class){
logger.info("updateSolrClient 开始写入类变量------------------------------------------12345---------------");
cloudSolrClient = temp;
}
}
}

在类加载的过程中 因为 test() 方法有 运行时异常抛出,所以加载过程停止 ,没有生成class类对象

问题: 第一次类加载 抛出异常失败,第二次 外部调用 更新update的时候 也是失败,为什么 不是重新 类加载呢?

从结论看问题: 第二次仍有 报错,第二次调用static方法 仍旧去进行类加载 结果仍旧报错。

问题延伸

Code
1
NoClassDefFoundError和ClassNotFoundException区别

一个是运行时 一个是编译时

Code
1
2
NoClassDefFoundError发生在JVM在动态运行时,根据你提供的类名 ,找不到这个类时,可能是因为 类加载未完成,都没有class对象 ,当然无法被使用,所以发生了java.lang.NoClassDefFoundError的错误, 
而ClassNotFoundException是在编译的时候在classpath中找不到对应的类而发生的错误
Code
1
2
编程注意事项:
class 类加载的时候 防止有运行时错误,如果有 可能会导致该错误,
Code
1
2
问题:如果第一次 加载失败, 但是第二次 传入的是正确的值,第二次是否会成功,
也就是说,类加载失败 第二次再调用是重新类加载 还是 直接报错

第一次调用,手动抛出异常,显示的是抛出的异常, 类加载class对象想生成失败

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class SolrUtils {
private final static Logger logger = LoggerFactory.getLogger(SolrUtils.class);

private static CloudSolrClient cloudSolrClient ;

static{
String zkHost = UGCSolrConfig.UGC_SEARCH_SOLR_ZKHOST;
if(!"error".equals(zkHost)){
test();
}

String a = "a";
logger.info("111111111");
}


public static SolrClient test() {
throw new ValidationRuntimeException("qwwweweee");
}
public static SolrClient getSolrClient() {
return cloudSolrClient;
}

private SolrUtils() {}

第一次失败之后,第二次再次调用 ,没有进入utils方法 就报错 NoClassDefFoundError , 因为 test 方法找不到utils的class对象

java.lang.NoClassDefFoundError: Could not initialize class com.SolrUtils

问题? 为什么第二次 不进行类加载 初始化:

第一次生成了class 对象 就不会 有noClassDef报错

猜测:第一次初始化的时候生成了 class对象,但是初始化失败 ,没有生成java可以使用的类型。所以 ,第二次在调用的时候 发现之前 加载了(比如生成了class对象或者其他flag)但是 使用的找不到可以使用的java 类型,所以报错。

文章作者: 美式不加糖
文章链接: http://yoursite.com/2020/02/04/NoClassDefFoundError/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 湖畔小屋
打赏
  • 微信
    微信
  • 支付寶
    支付寶