有时候我们会面临明明已经把某个jar加入到了环境里,可以运行的时候还是找不到。 那么我们有没有一种方法,可以直接看到各个类加载器加载了哪些jar,以及把哪些路 径加到了classpath里?
(一)实现代码
package org.geekbang.a_jvm.类加载器;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
/**
* @author 起凤
* @description: TODO:jar包路径排查
* @date 2022/3/6
*/
public class JvmClassLoaderPrintPath {
public static void main(String[] args) {
// 启动类加载器
URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
System.out.println("启动类加载器");
for (URL url : urls) {
System.out.println(" ==> " + url.toExternalForm());
}
// 扩展类加载器
printClassLoader("扩展类加载器", JvmClassLoaderPrintPath.class.getClassLoader().getParent());
// 应用类加载器
printClassLoader("应用类加载器", JvmClassLoaderPrintPath.class.getClassLoader());
}
public static void printClassLoader(String name, ClassLoader CL) {
if (CL != null) {
System.out.println(name + " ClassLoader ‐> " + CL.toString());
printURLForClassLoader(CL);
} else {
System.out.println(name + " ClassLoader ‐> null");
}
}
public static void printURLForClassLoader(ClassLoader CL) {
Object ucp = insightField(CL, "ucp");
Object path = insightField(ucp, "path");
ArrayList ps = (ArrayList) path;
for (Object p : ps) {
System.out.println(" ==> " + p.toString());
}
}
private static Object insightField(Object obj, String fName) {
try {
Field f = null;
if (obj instanceof URLClassLoader) {
f = URLClassLoader.class.getDeclaredField(fName);
} else {
f = obj.getClass().getDeclaredField(fName);
}
f.setAccessible(true);
return f.get(obj);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
(二)运行结果分析
从下面的打印结果可以看出,
- 启动类加载器:加载的目录是jdk中jre/lib/下的各个核心jar包
- 扩展类加载器: 加载 jre/lib/ext/下的各种jar包
- 应用类加载器: 加载了包括启动类加载器和扩展器加载器的内容,除此之外还包括本项目的路径
file:/D:/ideaProjects/jikeshijian/ji_ke_shi_jian/out/production/ji_ke_shi_jian/
这也就是为什么在没有使用自定义类加载器情况下,用户自定 义的类都由应用类加载器加载。
启动类加载器
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/resources.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/rt.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/sunrsasign.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/jsse.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/jce.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/charsets.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/jfr.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/classes
扩展类加载器 ClassLoader ‐> sun.misc.Launcher$ExtClassLoader@1b6d3586
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/access-bridge-64.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/cldrdata.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/dnsns.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/jaccess.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/jfxrt.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/localedata.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/nashorn.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/sunec.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/sunjce_provider.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/sunmscapi.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/sunpkcs11.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/zipfs.jar
应用类加载器 ClassLoader ‐> sun.misc.Launcher$AppClassLoader@18b4aac2
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/charsets.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/deploy.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/access-bridge-64.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/cldrdata.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/dnsns.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/jaccess.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/jfxrt.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/localedata.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/nashorn.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/sunec.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/sunjce_provider.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/sunmscapi.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/sunpkcs11.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/ext/zipfs.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/javaws.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/jce.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/jfr.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/jfxswt.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/jsse.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/management-agent.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/plugin.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/resources.jar
==> file:/D:/Program%20Files/Java/jdk1.8.0_241/jre/lib/rt.jar
==> file:/D:/ideaProjects/jikeshijian/ji_ke_shi_jian/out/production/ji_ke_shi_jian/
==> file:/D:/Program%20Files/JetBrains/ideaIU-2021.1.3.win/lib/idea_rt.jar
Process finished with exit code 0