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

时间:2011-09-28 22:38:45

标签: java jvm classpath diagnostics

我的代码失败了ClassNotFoundException

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

有没有办法从JVM转储类路径上的类列表? (理想情况下是一些Java代码)。

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

4 个答案:

答案 0 :(得分:11)

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

这样的事情:

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

它会产生类似于:

的输出
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, ...]

答案 1 :(得分:5)

  

..? (理想情况下是一些Java代码)

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

答案 2 :(得分:3)

如果你得到一个CNFE,那实际上并不是你想看到的,因为它没找到。此外,并非所有可用的课程都会在任何特定时间加载。

首先浏览this list。但总的来说,如果找不到,实际上找不到它。

答案 3 :(得分:0)

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

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

第三种替代方案(适用于Java 5+)将是VisualVM,它是Java6 +发行版的一部分。

但是,大多数情况下,您的jar文件不在类路径中,或者您正在使用一些自定义类加载器。您能详细说明如何将该jar放在类路径上吗?