Java 类加载器解析及常见类加载问题
点击下方“IT牧场”,选择“设为星标”
package java.lang;
public abstract class ClassLoader {
public Class loadClass(String name);
protected Class defineClass(byte[] b);
public URL getResource(String name);
public Enumeration getResources(String name);
public ClassLoader getParent()
}
public class A {
public void doSomething() {
B b = new B();
b.doSomethingElse();
}
}
类加载器层次结构
Java EE 委托模型
常见类加载问题
NoClassDefFoundError
public class HelloServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.print(new Util().sayHello());
}
java.lang.NoClassdefFoundError: Util
HelloServlet:doGet(HelloServlet.java:17)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
public class HelloServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.print(Arrays.toString(
((URLClassLoader)HelloServlet.class.getClassLoader()).getURLs()));
}
file:/Users/myuser/eclipse/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/demo/WEB-INF/classes,
file:/Users/myuser/eclipse/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/demo/WEB-INF/lib/demo-lib.jar
file:/Users/myuser/eclipse/workspace/.metadata/)实际上显示容器是从 Eclipse 启动的,这是 IDE 解压归档文件来进行部署的地方。现在我们可以检查丢失的 Util 是否真的包含在 demo-lib.jar 中,或者它是否存在于扩展存档的 WEB-INF/classes 目录中。
NoSuchMethodError
java.lang.NoSuchMethodError: Util.sayHello()Ljava/lang/String;
HelloServlet:doGet(HelloServlet.java:17)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
public class HelloServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.print(HelloServlet.class.getClassLoader().getResource(
Util.class.getName.replace(‘.’, ‘/’) + “.class”));
}
file:/Users/myuser/eclipse/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/demo/WEB-INF/lib/demo-lib.jar!/Util.class
$ javap -private Util
Compiled from “Util.java”
public class Util extends java.lang.Object {
public Util();
}
ClassCastException
public class HelloServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.print(((Util)Factory.getUtil()).sayHello());
}
class Factory {
public static Object getUtil() {
return new Util();
}
}
java.lang.ClassCastException: Util cannot be cast to Util
HelloServlet:doGet(HelloServlet.java:18)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
[Loaded Util from file:/Users/ekabanov/Applications/ apache-tomcat-6.0.20/lib/cl-shared-jar.jar]
[Loaded Util from file:/Users/ekabanov/Documents/workspace-javazone/.metadata/.plugins/org.eclipse.wst. server.core/tmp0/wtpwebapps/cl-demo/WEB-INF/lib/cl-demo- jar.jar]
LinkageError
class Factory {
public static Util getUtil() {
return new Util();
}
}
ClassCastException: java.lang.LinkageError: loader constraint violation: when resolving method Factory.getUtil()LUtil;
<…> HelloServlet:doGet(HelloServlet.java:18)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617) javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
IllegalAccessError
class Factory {
static Object getUtil() {
return new Util();
}
}
java.lang.IllegalAccessError: tried to access method Factory.getUtil()Ljava/lang/Object;
HelloServlet:doGet(HelloServlet.java:18)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
Java 类加载器备忘单
No class found
ClassNotFoundException
NoClassDefFoundError
IDE class lookup (Ctrl+Shift+T in Eclipse)
find *.jar -exec jar -tf '{}'; | grep MyClass
URLClassLoader.getUrls() Container specific logs
Wrong class found
IncompatibleClassChangeError AbstractMethodError NoSuch(Method|Field)Error
ClassCastException, IllegalAccessError
-verbose:class
ClassLoader.getResource() javap -private MyClass
More than one class found
LinkageError (class loading constraints violated)
ClassCastException, IllegalAccessError
-verbose:class
ClassLoader.getResource()
干货分享
最近将个人学习笔记整理成册,使用PDF分享。关注我,回复如下代码,即可获得百度盘地址,无套路领取!
•001:《Java并发与高并发解决方案》学习笔记;•002:《深入JVM内核——原理、诊断与优化》学习笔记;•003:《Java面试宝典》•004:《Docker开源书》•005:《Kubernetes开源书》•006:《DDD速成(领域驱动设计速成)》•007:全部•008:加技术群讨论
加个关注不迷路
喜欢就点个"在看"呗^_^
评论