NoClassDefFoundError && ClassNotFoundException
两种错误都是涉及类加载问题,类层次结构如下:

NoClassDefFoundError是系统错误,ClassNotFoundException是系统异常,可以捕获。 NoClassDefFoundError发生在对Class原始文件解析通过类的全限定名在类路径下无法找到相关类的定义时;ClassNotFoundException发生在通过调用Class.forName()、类加载器的loadClass/findClass在程序中自定义加载类时。
- 注: 以下测试代码文件夹层次结构: *

下面为NoClassDefFoundError测试程序,TestReference.java程序内引用google.guava包里的第三方类。在编译时将第三方的guava-23.0.jar加入到classpath里,编译通过,运行时不加classpath,然后程序就会抛出NoClassDefFoundError,通过异常堆栈可以看出,底层也是通过loadClass来尝试加载引用的类的。
import com.google.common.base.*;
import com.google.common.collect.*;
import java.util.*;
public class TestReference{
public static void main(String[] args){
Map<String,String> a = Maps.newHashMap();
}
}
javac -cp guava-23.0.jar TestReference.java
// 编译OK
java TestReference
// 报错:
// Exception in thread "main" java.lang.NoClassDefFoundError: com/google/common/col
// lect/Maps
// at TestReference.main(TestReference.java:6)
// Caused by: java.lang.ClassNotFoundException: com.google.common.collect.Maps
// at java.net.URLClassLoader.findClass(Unknown Source)
// at java.lang.ClassLoader.loadClass(Unknown Source)
// at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
// at java.lang.ClassLoader.loadClass(Unknown Source)
// ... 1 more
java TestReference -cp .;guava-23.0.jar
// 执行OK
通过研究Class文件结构可以得出以下结论: 当Java程序运行时,JVM加载TestReference.class文件,解析出methodRef下code属性里的代码内容,通过代码里写的类短名称加上import的空间定位引用类的全限定名,然后通过全限定名在类路径下加载相关的类,当没有找到时抛出该错误。这个错误是JVM抛出。
下面是ClassNotFoundException示例代码,ClassNotFoundException代码里通过Class.forName("") 加载google.guava的类:
public class TestClassForname{
public static void main(String[] args) throws Exception{
Class a = Class.forName("com.google.common.collect.Maps");
}
}
javac TestClassForname.java
// 编译OK
java TestClassForname
// Exception in thread "main" java.lang.ClassNotFoundException: com.google.common.c
// ollect.Maps
// at java.net.URLClassLoader.findClass(Unknown Source)
// at java.lang.ClassLoader.loadClass(Unknown Source)
// at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
// at java.lang.ClassLoader.loadClass(Unknown Source)
// at java.lang.Class.forName0(Native Method)
// at java.lang.Class.forName(Unknown Source)
// at TestClassForname.main(TestClassForname.java:4)
ClassNotFoundException这个异常的定义就是没有加载到类就抛出这个异常,上面说的NoClassDefFoundError底层也是通过抛出这个异常触发的,只不过JVM会在上面场合下通过捕获ClassNotFoundException然后转而抛出NoClassDefFoundError错误。
NoClassDefFoundError && ClassNotFoundException的更多相关文章
- Atitit.故障排除系列---NoClassDefFoundError NoClassDefFoundError ClassNotFoundException
Atitit.故障排除系列---NoClassDefFoundError NoClassDefFoundError ClassNotFoundException 1. java.lang.Class ...
- Eclipse在Tomcat环境下运行项目出现NoClassDefFoundError/ClassNotFoundException解决办法
For this error, there can be different solutions. I have noted down the ones that had worked for me. ...
- NoClassDefFoundError与ClassNotFoundException
原文地址: https://blog.csdn.net/jamesjxin/article/details/46606307 怎么解决NoClassDefFoundError错误 NoClassDef ...
- 项目 java.lang.NoClassDefFoundError 异常。
项目部署之后调用接口失败:异常信息: NoClassDefFoundError ClassNotFoundException 注意这两种是有区别的. 具体转 https://www.cnblogs.c ...
- JDK动态代理实现原理
之前虽然会用JDK的动态代理,但是有些问题却一直没有搞明白.比如说:InvocationHandler的invoke方法是由谁来调用的,代理对象是怎么生成的.直到看了他的文章才彻底明白,附网址:htt ...
- ProxyPattern
代理模式是aop编程的基础,其主要作用是操作对象,并将你需要的新功能切入若干个你想要的切入点,静态代理模式比较简单,但是缺点比较大,这里就不上代码了,下面写上动态代理模式的代码(jdk方式,而不是采用 ...
- java中InvocationHandler 用于实现代理。
以下的内容部分参考了网络上的内容,在此对原作者表示感谢! Java中动态代理的实现,关键就是这两个东西:Proxy.InvocationHandler,下面从InvocationHandler接口中的 ...
- Java 动态代理
被代理的接口特点: 1. 不能有重复的接口,以避免动态代理类代码生成时的编译错误. 2. 这些接口对于类装载器必须可见,否则类装载器将无法链接它们,将会导致类定义失败. 3. 需被代理的所有非 pub ...
- 代理模式 & Java原生动态代理技术 & CGLib动态代理技术
第一部分.代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常 ...
随机推荐
- Android短信验证码倒计时
有两种实现方法 1.第一种方式:Timer /** * Description:自定义Timer * <p> * Created by Mjj on 2016/12/4. */ publi ...
- 【Django】模型层说明
[Django模型层] 之前大概介绍Django的文章居然写了两篇..这篇是重点关注了Django的模型层来进行学习. ■ 模型定义 众所周知,Django中的模型定义就是定义一个类,其基本结构是这样 ...
- windows2003NLB群集配置(工作组和域)
详情地址查看:http://wenku.baidu.com/link?url=kiyyeZcSXZV9vLIZFbAlQXq1Qsm3_N0A7cue-qz6CorUYbXaGn-Ocfo49Qyal ...
- java排序算法(一):概述
java排序算法(一)概述 排序是程序开发中一种非常常见的操作,对一组任意的数据元素(活记录)经过排序操作后,就可以把它们变成一组按关键字排序的一组有序序列 对一个排序的算法来说,一般从下面三个方面来 ...
- Git常用命令(一)------ 本地操作
本文总结自廖雪峰的网站. 几个名词: 工作区(Working Directory):电脑里能看到的目录 版本库(Repository):包含暂存区和master 暂存区(Stage):待放入maste ...
- 关于php日期前置是否有0
例如:2018-01-04,这个日期和月份前置是有0 如果不想有0,date( 'y-n-j',time() ):默认的是date( 'y-m-d',time() ),这个日期和月份前置是有0. da ...
- 微信公众号报错 config:invalid signature
官方已经提供了微信 JS 接口签名校验工具(http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign),填入相应的参数就能出来相应的signa ...
- Java基础学习笔记二十二 网络编程
络通信协议 通过计算机网络可以使多台计算机实现连接,位于同一个网络中的计算机在进行连接和通信时需要遵守一定的规则,这就好比在道路中行驶的汽车一定要遵守交通规则一样.在计算机网络中,这些连接和通信的规则 ...
- Property 'id' not found on type java.lang.String
改为 忘写了$符,取不出来,因此报错!
- 20162323周楠《Java程序设计与数据结构》第五周总结
20162323周楠 2016-2017-2 <程序设计与数据结构>第五周学习总结 教材学习内容总结 1.面向对象软件设计的基本部分是确定程序中应该创建哪些类: 2.面向对象程序设计的核心 ...