繁体   English   中英

如何找到类加载器加载的罐子和顺序?

[英]How to find which jars and in what order are loaded by a classloader?

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

是否有某种方式(编程或其他方式)以按照它们加载的精确顺序获取由Application Classloader加载的JAR /类列表? 按应用程序类加载器我的意思是在应用程序服务器(WLS,WAS,JBoss ...)中加载EAR应用程序的类加载器,但显然,它适用于任何类加载器。

因此,为了概括,我想知道的是由指定的类加载器加载的JAR的列表和顺序。 不是单个类,通过调用classloader.getPackages()很容易找到,但是这个类加载器加载的JAR文件列表。

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

最简洁的答案是不。 类加载器不需要公开其搜索逻辑。

但是,如果您的类加载器实例恰好是URLClassLoader或子类,那么您可以通过getURLs()方法访问jar /目录列表。 根据此类的文档,将按顺序搜索这些URL。

在实践中,如果你试图找出一个类的加载位置, 史蒂夫的回答可能更有用。

浏览类的保护域(位置/证书组合)。 例如,对于PDFParser.class,你会得到这样的......

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

如果从jre类或者背书dirs加载它会抛出一个异常因为这些类在没有保护的情况下加载...

作为替代方法,您可以使用此代码段。 结果是一个文件,它由相关的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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM