NoClassDefFoundError 错误说明
1 2 3 4 5
| Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.SolrUtils
class类对象没有加载成功,在程序调用该类static方法的时候,因为没有这个类对象 所以找不到 ,会报异常 错误原因: 在 类加载 的工程中,有异常抛出 导致 类加载 未完成,class 类对象没有生成
|
NoClassDefFoundError错误的发生,是因为Java虚拟机在编译时能找到合适的类,而在运行时不能找到合适的类导致的错误。
测试demo
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方法 仍旧去进行类加载 结果仍旧报错。
问题延伸
1
| NoClassDefFoundError和ClassNotFoundException区别
|
一个是运行时 一个是编译时
1 2
| NoClassDefFoundError发生在JVM在动态运行时,根据你提供的类名 ,找不到这个类时,可能是因为 类加载未完成,都没有class对象 ,当然无法被使用,所以发生了java.lang.NoClassDefFoundError的错误, 而ClassNotFoundException是在编译的时候在classpath中找不到对应的类而发生的错误
|
1 2
| 编程注意事项: class 类加载的时候 防止有运行时错误,如果有 可能会导致该错误,
|
1 2
| 问题:如果第一次 加载失败, 但是第二次 传入的是正确的值,第二次是否会成功, 也就是说,类加载失败 第二次再调用是重新类加载 还是 直接报错
|
第一次调用,手动抛出异常,显示的是抛出的异常, 类加载class对象想生成失败
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 类型,所以报错。