#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. это интересно.