java 从 JVM 内部转储类路径上的类的方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7590495/
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-10-30 20:36:35  来源:igfitidea点击:

Method to dump classes on the classpath from inside JVM?

javajvmclasspathdiagnostics

提问by hawkeye

My code is failing with a ClassNotFoundException.

我的代码因ClassNotFoundException.

I can see that the jar file containing the class is definitely on the classpath from the command prompt execution.

我可以从命令提示符执行中看到包含该类的 jar 文件肯定在类路径上。

Is there a way to dump the list of classes on the classpath from the JVM? (Ideally some Java code).

有没有办法从 JVM 转储类路径上的类列表?(最好是一些 Java 代码)。

(I don't want to see the classes in a directory, I want to see a list of what is loaded into the JVM).

(我不想看到目录中的类,我想看到加载到 JVM 中的内容的列表)。

采纳答案by Dave Newton

That's actually not what you want to see if you're getting a CNFE, since it's not found. Plus not all available classes will be loaded at any given time.

如果您得到CNFE,那实际上不是您想要看到的,因为它没有被找到。此外,并非所有可用的类都会在任何给定时间加载。

Start by going through this list. But in general, if it's not found, it's actually not found.

从浏览这个列表开始。但一般情况下,如果没有找到,实际上是没有找到。

回答by prunge

You can programatically display the classpath by looking at the classloaders and dumping the URLs they are loading from.

您可以通过查看类加载器并转储它们从中加载的 URL 以编程方式显示类路径。

Something like this:

像这样的东西:

import java.net.URLClassLoader;
import java.util.Arrays;

public class ClasspathDumper
{
    public static void main(String... args)
    {
        dumpClasspath(ClasspathDumper.class.getClassLoader());
    }

    public static void dumpClasspath(ClassLoader loader)
    {
        System.out.println("Classloader " + loader + ":");

        if (loader instanceof URLClassLoader)
        {
            URLClassLoader ucl = (URLClassLoader)loader;
            System.out.println("\t" + Arrays.toString(ucl.getURLs()));
        }
        else
            System.out.println("\t(cannot display components as not a URLClassLoader)");

        if (loader.getParent() != null)
            dumpClasspath(loader.getParent());
    }
}

it would produce output similar to:

它将产生类似于以下内容的输出:

Classloader sun.misc.Launcher$AppClassLoader@2a340e:
    [file:/C:/Java/workspaces/myproject/bin/]
Classloader sun.misc.Launcher$ExtClassLoader@bfbdb0:
    [file:/C:/Java/jdk/jdk1.7.0/jre/lib/ext/dnsns.jar, file:/C:/Java/jdk/jdk1.7.0/jre/lib/ext/localedata.jar, file:/C:/Java/jdk/jdk1.7.0/jre/lib/ext/sunec.jar, file:/C:/Java/jdk/jdk1.7.0/jre/lib/ext/sunjce_provider.jar, ...]

回答by Rajeev Sreedharan

..? (Ideally some Java code)

..?(最好是一些 Java 代码)

If you were looking only to resolve a Class-Not-Found bug, then adding a dump code within the app can add complexity to turn it off later. Perhaps it would be better to use -verbose:classJVM argument which would output all classes loaded at runtime. Its easy to turn off and output of the console can be easily redirected to a log.

如果您只想解决 Class-Not-Found 错误,那么在应用程序中添加转储代码可能会增加稍后将其关闭的复杂性。也许最好使用-verbose:classJVM 参数来输出在运行时加载的所有类。它很容易关闭,控制台的输出可以很容易地重定向到日志。

回答by Thomas

Well, you could create a memory dump (e.g. via jmap) and view it (e.g. via jhat).

好吧,您可以创建内存转储(例如通过 jmap)并查看它(例如通过 jhat)。

Alternatively, IIRC jconsole can show the loaded classes, so you could just view them. I'm not entirely sure though and I don't have a running jconsole right now.

或者,IIRC jconsole 可以显示加载的类,因此您可以查看它们。我不完全确定,我现在没有正在运行的 jconsole。

A third alternative (for Java 5+) would be VisualVMwhich is part of the Java6+ distribution.

第三种选择(对于 Java 5+)是VisualVM,它是 Java6+ 发行版的一部分。

However, most certainly your jar file is not on the classpath or you are using some custom classloaders. Could you elaborate on how you put that jar on the classpath?

但是,可以肯定的是,您的 jar 文件不在类路径中,或者您正在使用某些自定义类加载器。你能详细说明你如何把那个 jar 放在类路径上吗?