如何find哪个jar子和按什么顺序由类加载器加载?

我在其他地方找不到这个问题的明确答案,所以我会在这里尝试:

有没有某种方式(编程或其他)来获取应用程序类加载器加载的JAR /类的列表,按照它们加载的精确顺序? 通过应用程序类加载器我指的是在应用程序服务器(WLS,WAS,JBoss …)中加载EAR应用程序的类加载器,但显然它适用于任何类加载器。

所以,一般来说,我想知道的是由指定的类加载器加载的JAR的列表和顺序。 不是单独的类,这很容易通过调用classloader.getPackages()来find,而是由此类加载器加载的JAR文件的列表。

最简洁的答案是不。 类加载器不需要公开他们的search逻辑。

但是,如果您的类加载器实例恰好是URLClassLoader或一个子类,那么您可以通过getURLs()方法访问jars /目录列表。 根据该课程的文档,这些url将按顺序search。

在实践中,如果你正在试图找出一个类是从哪里加载的, Steve的答案可能更有用。

您是否尝试过使用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] 

浏览课程的保护域(位置/证书组合)。 例如PDFParser.class,你可以像这样…

 PDFParser.class.getProtectionDomain().getCodeSource().getLocation().toString() 

如果它是从jre类加载或从背书dir它会抛出一个例外cos这些类加载没有保护…

作为替代方法,您可以使用此代码段。 结果是一个由相关的jar文件组成的文件,这个文件是由一个对象的类加载器(类加载器的链,包括其父类,直到根类加载器)加载的类加载器和类文件。 class级装载机由星星分开。

 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); }