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

后端 未结 4 1135
离开以前
离开以前 2020-12-12 20:37

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 A

相关标签:
4条回答
  • 2020-12-12 21:09

    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]
    
    0 讨论(0)
  • 2020-12-12 21:18

    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.

    0 讨论(0)
  • 2020-12-12 21:20

    Go through the Protection Domain of the class (the location/certificate combination). e.g. 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...

    0 讨论(0)
  • 2020-12-12 21:31

    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);
    }
    
    0 讨论(0)
提交回复
热议问题