Ответ 1
Передача переключателя -verbose:class
в команду java
будет печатать каждый загруженный класс и где он был загружен.
Joops также является хорошим инструментом для поиска недостающих классов раньше времени.
Есть ли способ определить, какие классы загружаются из банок во время выполнения?
Я уверен, что мы все были в JAR ад раньше. Я столкнулся с этой проблемой много проблем с поиском ClassNotFoundException
и NoClassDefFoundError
для проектов. Я бы хотел избежать поиска всех экземпляров класса в баночках и использования процесса устранения кода, вызывающего CNFE, чтобы найти виновника.
Будут ли какие-либо инструменты профилирования или управления предоставлять вам такую информацию?
Эта проблема очень раздражает, потому что мы должны иметь эту информацию во время загрузки класса. Должен быть способ добраться до него или записать его и найти, но я ничего не знаю, что сделаю это, не так ли?
Я знаю, что OSGi и версии пакетов/модулей нацелены на то, чтобы сделать это не проблемой... но, похоже, в ближайшее время он не уйдет.:)
ПРИМЕЧАНИЕ. Я обнаружил, что это question является подмножеством моего вопроса, связанного с классами, загружаемыми с версированных банок.
Обновление. В некоторой степени это объясняет стратегию поиска класса внутри jars (либо в текущем каталоге), либо в вашем M2_REPO. JarScan, сканировать все файлы JAR во всех подпапках для определенного класса
Обновление 2: также несколько связано, JBoss Tattletale
Передача переключателя -verbose:class
в команду java
будет печатать каждый загруженный класс и где он был загружен.
Joops также является хорошим инструментом для поиска недостающих классов раньше времени.
Из кода, который вы можете вызвать:
myObject.getClass().getProtectionDomain().getCodeSource()
(Примечание. getProtectionDomain
может, к сожалению, возвратить null
(плохой дизайн), поэтому для этого будет проверен "правильный код".)
Существует MBean для флага JVM, упомянутого выше в Jason Day.
Если вы используете JBoss, вы можете покрутить это по требованию с помощью JMX, если вы добавите собственный JMX-сервер MBean в свою конфигурацию. Добавьте следующие -D:
-Dcom.sun.management.jmxremote.port=3333
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djboss.platform.mbeanserver
-Djavax.management.builder.initial=org.jboss.system.server.jmx.MBeanServerBuilderImpl
-DJBOSS_CLASSPATH="../lib/jboss-system-jmx.jar"
И затем вы можете увидеть этот параметр в разделе java.lang: Classloading MBean и можете в любое время разрезать его/выключить. Это полезно, если вы только хотите, чтобы он выполнял определенный фрагмент кода.
Существует также MBean, который позволит вам ввести полное имя класса и посмотреть, где он был загружен из иерархии классов. MBean называется LoaderRepository, и вы хотите вызвать операцию displayClassInfo(), передав FQCN.
В WebSphere (WAS) вы можете использовать функцию "Class Loader Viewer"
Сначала включите средство просмотра загрузчика классов, щелкнув "Серверы" > "Типы серверов" > "Серверы приложений WebSphere" > "имя_сервера" > "Служба просмотра загрузчика класса", включите службу и перезапустите сервер.
Затем вы можете перейти в "Устранение неполадок" > "Просмотрщик классов" и выполнить поиск имени вашего класса или пакета.
Вы можете легко экспортировать операцию JMX для доступа к информации о пакете для любого загруженного класса в вашем процессе, например:
public static final class Jmx {
@JmxExport
public static Reflections.PackageInfo getPackageInfo(@JmxExport("className") final String className) {
return Reflections.getPackageInfo(className);
}
}
и вот простой unit test для экспорта и вызова:
@Test
public void testClassLocator() throws IOException, InstanceNotFoundException, MBeanException, ReflectionException {
Registry.export(Jmx.class);
Reflections.PackageInfo info = (Reflections.PackageInfo) Client.callOperation(
"service:jmx:rmi:///jndi/rmi://:9999/jmxrmi",
Jmx.class.getPackage().getName(),
Jmx.class.getSimpleName(), "getPackageInfo", Registry.class.getName());
System.out.println(info);
Assert.assertNotNull(info);
}
все это основано на использовании небольшой библиотеки утилит из spf4j (http://www.spf4j.org)