我在其他地方找不到这个问题的明确答案,所以我会在这里试试:
是否有某种方式(编程或其他方式)以加载的精确顺序获取Application Classloader加载的JAR /类列表? 应用程序类加载器我的意思是在应用程序服务器(WLS,WAS,JBoss ......)中加载EAR应用程序的类加载器,但显然,它适用于任何类加载器。
因此,为了概括,我想知道的是由指定的类加载器加载的JAR的列表和顺序。不是单个类,通过调用classloader.getPackages()很容易找到,但是这个类加载器加载的JAR文件列表。
答案 0 :(得分:72)
您是否尝试过使用JVM选项-verbose:class
。它显示所有已加载的JAR文件和类。
示例:
[Opened C:\Program Files\JDK160~1\jre\lib\rt.jar]
[Loaded java.lang.Object from C:\Program Files\JDK160~1\jre\lib\rt.jar]
答案 1 :(得分:13)
简短的回答是否定的。类加载器不需要公开其搜索逻辑。
但是,如果您的类加载器实例恰好是URLClassLoader或子类,那么您可以通过getURLs()
方法访问jar /目录列表。根据此类的文档,将按顺序搜索这些URL。
在实践中,如果你试图找出一个类的加载位置, Steve 的答案可能更有用。
答案 2 :(得分:1)
浏览班级的保护域(位置/证书组合)。例如对于PDFParser.class,你可以这样得到它......
PDFParser.class.getProtectionDomain().getCodeSource().getLocation().toString()
如果它是从jre类或者背书目录中加载的,那么它会抛出异常,因为这些类加载时没有保护...
答案 3 :(得分:0)
作为替代方法,您可以使用此代码段。结果是一个文件,它由相关的jar文件组成一个类加载器和类文件,这些文件由一个对象的类加载器(类加载器链,包括它的父类直到root类加载器)加载。班级装载者由明星分开。
Object obj = this;
ClassLoader classLoader = obj.getClass().getClassLoader();
File file = new File("classlodersClassesJars.txt");
if(file.exists()) {
file.delete();
}
if(classLoader != null) { // to escape from system classes that are loaded by bootstrap class-loader such as String.
do {
try {
Class clClass = classLoader.getClass();
while(clClass != ClassLoader.class){
clClass = clClass.getSuperclass();
}
java.lang.reflect.Field domainField = clClass.getDeclaredField("domains");
java.lang.reflect.Field classesField = clClass.getDeclaredField("classes");
domainField.setAccessible(true);
classesField.setAccessible(true);
HashSet domains = (HashSet<String>) domainField.get(classLoader);
Vector classes = (Vector) classesField.get(classLoader);
FileOutputStream fos = new FileOutputStream("classlodersClassesJars.txt", true);
fos.write(("\n******************** " + classLoader.toString() + "\n").getBytes());
fos.write(Arrays.toString(classes.toArray()).getBytes());
Object[] reverseDomains = domains.toArray();
org.apache.commons.lang.ArrayUtils.reverse(reverseDomains);
fos.write(Arrays.toString(reverseDomains).getBytes());
fos.close();
classLoader = classLoader.getParent();
} catch (Exception exception) {
exception.printStackTrace();
// TODO
}
} while (classLoader.getParent() != null);
}