简体   繁体   中英

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

I could not find a clear answer to this question elsewhere, so I'll try here:

Is there some way (programmatic or other) to get a list of JARs/classes loaded by an Application Classloader in the precise order they were loaded? By Application Classloader I mean the classloader that loads an EAR application in an applications server (WLS, WAS, JBoss...), but obviously, it applies to any classloader.

So, to generalize, what I would like to find out is the list and order of JARs loaded by a specified classloader. Not individual classes, that is easy enough to find out by calling the classloader.getPackages(), but a list of JAR files that were loaded by this classloader.

Have you tried to use the JVM option -verbose:class . It displays all loaded JAR files and classes.

Example:

[Opened C:\Program Files\JDK160~1\jre\lib\rt.jar]
[Loaded java.lang.Object from C:\Program Files\JDK160~1\jre\lib\rt.jar]

The short answer is no. Classloaders are not required to expose their search logic.

However, if your classloader instance happens to be URLClassLoader or a subclass, then you do have access to the list of jars/directories, via the getURLs() method. Per the doc for this class, those URLs will be searched in order.

In practice, if you're trying to find out where a class is being loaded from, Steve 's answer is probably more useful.

Go through the Protection Domain of the class (the location/certificate combination). eg for PDFParser.class you get it like this...

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

If it is loaded from the jre classes or from endorsed dirs it will throw an exception cos these classes load without protection...

As an alternative way, you can use this code snippet. The result is a file that consist of related jar files to a class-loader and class files that are loaded by an object's class-loaders (chain of class-loaders including its parents until root class-loader). Class-loaders are seperated by stars.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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