编写一个web工程能打印出自己的类加载器名称和当前类加载器的父子结构关系链的MyServlet,
代码如下- ClassLoader loader=MyServlet.class.getClassLoader();
- out.println(loader.getClass().getName());
- out.close();
- }
复制代码 运行的结果,MyServlet是WebappClassLoader类加载器 加载的
如果我们要是把MyServlet打成jar包,放在 JRE/lib/ext/*.jar目录中,这时程序就会报错,出现NoClassDefFoundError异常,
出现这种异常表明HttpServlet该类无法加载。
原因是因为如果MyServlet类 jar包放在CLASSPATH指定的所有jar或目录时,这时WebappClassLoader类加载器 去加载MyServlet
这个类, 由于MyServlet类 继承了HttpServlet,所以WebappClassLoader也去加载HttpServlet类
如果MyServlet类 jar包放在JRE/lib/ext/*.jar目录中,这时ExtClassLoader这个 类加载去加载,但是MyServlet可以被ExtClassLoader
加载,HttpServlet则不能被ExtClassLoader加载,这时类加载器的委托给父类去加载,这时父类也不能加载HttpServlet类, 这时java虚拟机就会报错,出现了NoClassDefFoundError异常,就不会交给子类加载器去加载的
如图所示
处理的方法: 就是把HttpServlet的jar包也放在JRE/lib/ext/*.jar目录中,都让ExtClassLoader类加载器去加载,这时运行成功。
|