Найти, где class java загружен из

Кто-нибудь знает, как программно узнать, откуда загружается class java classloader?

Я часто работаю над крупными проектами, где classpath становится очень длинным, а ручной поиск на самом деле не вариант. У меня недавно возникла проблема, когда загрузчик classов загружал некорректную версию classа, потому что он находился на пути к classам в двух разных местах.

Итак, как я могу заставить classloader сказать мне, где на диске появился фактический файл classа?

Изменить: что, если загрузчик classов фактически не загружает class из-за несоответствия версии (или что-то еще), есть ли способ узнать, какой файл пытается его прочитать, прежде чем он его прочитает?

Вот пример:

package foo; public class Test { public static void main(String[] args) { ClassLoader loader = Test.class.getClassLoader(); System.out.println(loader.getResource("foo/Test.class")); } } 

Это напечатано:

 file:/C:/Users/Jon/Test/foo/Test.class 

Другой способ узнать, откуда загружен class (без использования источника), – запустить виртуальную -verbose:class Java с помощью опции: -verbose:class

 getClass().getProtectionDomain().getCodeSource().getLocation(); 

Это то, что мы используем:

 public static String getClassResource(Class klass) { return klass.getClassLoader().getResource( klass.getName().replace('.', '/') + ".class").toString(); } 

Это будет работать в зависимости от реализации ClassLoader: getClass().getProtectionDomain().getCodeSource().getLocation()

Версия Jon терпит неудачу, когда ClassLoader объекта зарегистрирован как null что, по-видимому, означает, что он был загружен Boot ClassLoader .

Этот метод касается этой проблемы:

 public static String whereFrom(Object o) { if ( o == null ) { return null; } Class c = o.getClass(); ClassLoader loader = c.getClassLoader(); if ( loader == null ) { // Try the bootstrap classloader - obtained from the ultimate parent of the System Class Loader. loader = ClassLoader.getSystemClassLoader(); while ( loader != null && loader.getParent() != null ) { loader = loader.getParent(); } } if (loader != null) { String name = c.getCanonicalName(); URL resource = loader.getResource(name.replace(".", "/") + ".class"); if ( resource != null ) { return resource.toString(); } } return "Unknown"; } 

Изменить только 1-ю строку: Main .class

 Class c = Main.class; String path = c.getResource(c.getSimpleName() + ".class").getPath().replace(c.getSimpleName() + ".class", ""); System.out.println(path); 

Вывод:

 /C:/Users/Test/bin/ 

Может быть, плохой стиль, но отлично работает!

Взгляните на этот похожий вопрос. Инструмент для обнаружения того же classа ..

Я думаю, что наиболее важным препятствием является то, что у вас есть пользовательский загрузчик classов (загрузка из db или ldap)

Как правило, мы не используем hardcoding. Сначала мы можем получить className, а затем использовать ClassLoader для получения URL-адреса classа.

  String className = MyClass.class.getName().replace(".", "/")+".class"; URL classUrl = MyClass.class.getClassLoader().getResource(className); String fullPath = classUrl==null ? null : classUrl.getPath(); 

Этот подход работает как для файлов, так и для банок:

 Class clazz = Class.forName(nameOfClassYouWant); URL resourceUrl = clazz.getResource("/" + clazz.getCanonicalName().replace(".", "/") + ".class"); InputStream classStream = resourceUrl.openStream(); // load the bytecode, if you wish 

Предполагая, что вы работаете с classом MyClass , должно работать следующее:

 MyClass.class.getClassLoader(); 

Независимо от того, вы можете получить локальное расположение файла .class на диске, зависит от самого загрузчика classа. Например, если вы используете что-то вроде BCEL, определенный class может даже не иметь представления на диске.

  • Как читать определенную строку, используя определенный номер строки из файла на Java?
  • Чтение блокировки ввода InputStream Java
  • весовой коэффициент прокси-бэка
  • Как скопировать файл в банку за пределы банки?
  • Как производить JSON-выход с использованием Джерси-1.6 с использованием JAXB
  • Вручную вызовите функцию Spring Annotation Validation
  • Maven: Что такое pluginManagement?
  • В чем причина «нестатического метода нельзя ссылаться из статического контекста»?
  • Почему ваш тип данных оператора switch не может быть длинным, Java?
  • Группа захвата regex java
  • Конструкторы Java
  • Давайте будем гением компьютера.