Java 类加载器解析及常见类加载问题
Java引导者
共 9687字,需浏览 20分钟
·
2022-05-20 19:08
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()
欢迎关注“Java引导者”,我们分享最有价值的Java的干货文章,助力您成为有思想的Java开发工程师!
评论