Способ сброса классов по пути к классам из JVM?

#java #jvm #classpath #diagnostics

#java #jvm #classpath #диагностика

Вопрос:

Мой код терпит неудачу с a ClassNotFoundException .

Я вижу, что файл jar, содержащий класс, определенно находится в classpath из командной строки. Выполнение.

Есть ли способ дампа списка классов в пути к классам из JVM? (В идеале, некоторый Java-код).

(Я не хочу видеть классы в каталоге, я хочу увидеть список того, что загружено в JVM).

Комментарии:

1. Ответы на этот вопрос служат другому вопросу: «Как я могу определить, какие ресурсы classpath не удалось загрузить во время инициализации JVM?» — безопасность? файл не найден? и т.д.? как вы получаете список «тех, кто это сделал», а не «тех, кто этого не сделал?»

Ответ №1:

Вы можете программно отобразить classpath, просмотрев загрузчики классов и сбросив 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. Очень отличная функция — перечисляет ли это банки и каталоги, которые попали в classpath … и не отображают те, которые этого не сделали?

Ответ №2:

..? (В идеале, некоторый Java-код)

Если вы искали только для устранения ошибки, не обнаруженной в классе, то добавление кода дампа в приложение может усложнить его последующее отключение. Возможно, было бы лучше использовать -verbose:аргумент JVM класса, который выводил бы все классы, загруженные во время выполнения. Его легко отключить, и вывод консоли можно легко перенаправить в журнал.

Комментарии:

1. перечисляет ли это классы и ресурсы, которые попали в classpath … и не отображают те, которые этого не сделали? хм

Ответ №3:

На самом деле это не то, что вы хотите увидеть, если получаете a CNFE , поскольку оно не найдено. Плюс не все доступные классы будут загружены в любой момент времени.

Начните с просмотра этого списка. Но в целом, если он не найден, он на самом деле не найден.

Комментарии:

1. Хорошая информация — особенно если у вас есть опечатка в вашем classpath. Спасибо, что определили «ложный путь».

Ответ №4:

Ну, вы могли бы создать дамп памяти (например, через jmap) и просмотреть его (например, через jhat).

В качестве альтернативы, IIRC jconsole может отображать загруженные классы, чтобы вы могли просто просмотреть их. Я не совсем уверен, и у меня сейчас нет запущенного jconsole.

Третьей альтернативой (для Java 5 ) будет VisualVM, который является частью дистрибутива Java6 .

Однако, скорее всего, ваш файл jar отсутствует в classpath или вы используете какие-то пользовательские загрузчики классов. Не могли бы вы подробнее рассказать о том, как вы помещаете этот jar в classpath?

Комментарии:

1. Я не знал, что jmap предоставит вам ресурсы, загруженные в classpath. это интересно.