4

我的代码因ClassNotFoundException.

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

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

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

4

4 回答 4

12

您可以通过查看类加载器并转储它们从中加载的 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, ...]
于 2011-09-28T22:50:47.720 回答
5

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

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

于 2011-09-29T03:51:18.723 回答
3

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

从浏览这个列表开始。但总的来说,如果没有找到,实际上是没有找到。

于 2011-09-28T22:49:39.827 回答
0

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

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

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

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

于 2011-09-28T22:47:21.510 回答