Java 有没有办法获取 ClassLoader 加载了哪些类?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1432180/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 12:00:47  来源:igfitidea点击:

Is there a way to get which classes a ClassLoader has loaded?

javaunit-testingjvmclassloader

提问by uriDium

I am trying to implement some unit testing for an old framework. I am attempting to mock out the database layer. Unfortunately our framework is a bit old and not quite using best practices so there is no clear separation of concerns. I am bit worried that trying to mock out the database layer might make the JVM load a huge number of classes that won't even be used.

我正在尝试为旧框架实施一些单元测试。我正在尝试模拟数据库层。不幸的是,我们的框架有点旧,没有完全使用最佳实践,因此没有明确的关注点分离。我有点担心尝试模拟数据库层可能会使 JVM 加载大量甚至不会使用的类。

I don't really understand class loaders that well so this might not be a problem. Is there a way to take a peak at all the classes a particular ClassLoader has loaded to prove what is going on under the hood?

我不太了解类加载器,所以这可能不是问题。有没有办法在特定 ClassLoader 加载的所有类上达到峰值以证明幕后发生了什么?

采纳答案by Kelly S. French

Be warned that using

请注意,使用

java -verbose

Will produce an enormous amount of output. Log the output to a file and then use grep. If you have the 'tee' filter you could try this:

将产生巨大的产量。将输出记录到文件中,然后使用 grep。如果你有 'tee' 过滤器,你可以试试这个:

java -verbose | tee classloader.log
grep class classloader.log

回答by Suraj Chandran

I am not sure. But there is one way I see it could be done. It maybe overrly ridiculous though. You can try aspects and put a pointcut for loadclass. Also maybe the jvm argument -verbosemaybe helpful.

我不确定。但我认为有一种方法可以做到。不过,这可能过于荒谬了。您可以尝试方面并为 loadclass 放置一个切入点。也可能 jvm 参数-verbose可能有帮助。

回答by Alex Miller

You can create your own Classloader and use that to load during the unit test. Have your own custom Classloader print out what it's doing.

您可以创建自己的类加载器并在单元测试期间使用它来加载。让您自己的自定义类加载器打印出它在做什么。

Or if you just want to know which classes are loaded, do:

或者,如果您只想知道加载了哪些类,请执行以下操作:

java -verbose:class

回答by MMKarami

As an alternative way, for a particular Class-loader as you mentioned, you can use this code snippet. Just change value of obj variable if you want.

作为替代方法,对于您提到的特定类加载器,您可以使用此代码片段。如果需要,只需更改 obj 变量的值。

Object obj = this;
ClassLoader classLoader = obj.getClass().getClassLoader();
File file = new File("classloderClasses.txt");
if (file.exists()) {
    file.delete();
}
if (classLoader != null) {
    try {
        Class clClass = classLoader.getClass();
        while (clClass != ClassLoader.class) {
            clClass = clClass.getSuperclass();
        }
        java.lang.reflect.Field classesField = clClass.getDeclaredField("classes");
        classesField.setAccessible(true);
        Vector classes = (Vector) classesField.get(classLoader);
        FileOutputStream fos = new FileOutputStream("classloderClasses.txt", true);
        fos.write(("******************** " + classLoader.toString() + " ******************** " + "\n").getBytes());
        fos.write(Arrays.toString(classes.toArray()).getBytes());
        fos.close();
    } catch (Exception exception) {
        exception.printStackTrace();
        // TODO
    }
}