как узнать, какие классы загружаются из каких jar-файлов?

<p>есть ли способ определить, какие классы загружаются из каких jar-файлов во время выполнения?</p><p>я уверен, что мы все были в аду jar раньше. я сталкивался с этой проблемой много проблем с <code>classnotfoundexception</code>s и <code>noclassdeffounderror</code>s в проектах. я хотел бы избежать нахождения всех экземпляров класса в jar-файлах и использования процесса исключения в коде, в результате чего cnfe находит виновника.</p><p>будут ли какие-либо инструменты профилирования или управления давать вам такую информацию?</p><p>эта проблема очень раздражает просто потому, что мы должны иметь эту информацию во время загрузки класса. должен быть способ добраться до него или записать его и найти, но я ничего не знаю, что будет делать это, не так ли?</p><p>я знаю, osgi и версионные комплекты/модули стремятся сделать это не проблемой ... но, похоже, в ближайшее время это не исчезнет. :)</p><p>примечание: я нашел этот <a href="https://stackoverflow.com/questions/139534/classloader-issues-how-to-determine-which-library-versions-jar-files-are-load">вопрос</a> это подмножество моего вопроса, связанного с классами, загруженными из версионных jar-файлов.</p><p><strong>update</strong>: в некотором родстве этот пост объясняет стратегию поиска класса в jar-файлах (либо в текущем каталоге), либо в вашем m2\_repo. <a href="https://stackoverflow.com/questions/759923/jarscan-scan-all-jar-files-in-all-subfolders-for-specific-class">jarscan, просканируйте все файлы jar во всех подпапках для определенного класса</a> </p><p><strong>обновление 2</strong>: также несколько связано, <a href="http://docs.jboss.org/tattletale/developerguide/en/html\_single/">jboss tattletale</a> </p>

<p>передача переключателя <code>-verbose:class</code> команде <code>java</code> напечатает каждый загруженный класс и откуда он был загружен.</p><p> <a href="http://code.google.com/p/joops/">joops</a> также хороший инструмент для поиска пропущенных классов заранее.</p>

<p>из кода можно позвонить:</p><pre><code>myobject.getclass().getprotectiondomain().getcodesource() </code></pre><p>(обратите внимание, что <code>getprotectiondomain</code> может, к сожалению, возвращать <code>null</code> (плохой дизайн), поэтому «правильный код» проверит это.)</p>

<p>существует флаг mbean для флага jvm, упомянутого jason day выше.</p><p>если вы используете jboss, вы можете изменить это по требованию, используя jmx, если вы добавите нативный сервер jmx mbean в свою конфигурацию. добавьте следующие -d:</p><pre><code>-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" </code></pre><p>и тогда вы можете увидеть эту настройку в java.lang: classelling mbean и можете включить/выключить ее на лету. это полезно, если вы хотите включить его только при выполнении определенного фрагмента кода.</p><p>существует также mbean, который позволит вам ввести полное имя класса и посмотреть, откуда оно было загружено в иерархии классов. mbean называется loaderrepository, и вы захотите вызвать операцию displayclassinfo (), передавая fqcn.</p>

<p>в websphere (was) вы можете использовать функцию под названием «class loader viewer»</p><p>сначала включите средство просмотра загрузчика классов, щелкнув серверы> типы серверов> серверы приложений websphere> имя\_сервера> служба просмотра загрузчика классов, включите службу и перезапустите сервер.</p><p>затем вы можете перейти к разделу «устранение неполадок»> «средство просмотра загрузчика классов» и выполнить поиск вашего класса или имени пакета.</p><p> <a href="https://www-01.ibm.com/support/knowledgecenter/ssaw57\_8.5.5/com.ibm.websphere.nd.doc/ae/ttrb\_classload\_viewer.html?lang=en">https://www-01.ibm.com/support/knowledgecenter/ssaw57\_8.5.5/com.ibm.websphere.nd.doc/ae/ttrb\_classload\_viewer.html?lang=en</a> </p>

<p>вы можете легко экспортировать операцию jmx для доступа к информации о пакете для любого загруженного класса в вашем процессе, например:</p><pre><code> public static final class jmx { @jmxexport public static reflections.packageinfo getpackageinfo(@jmxexport("classname") final string classname) { return reflections.getpackageinfo(classname); } } </code></pre><p>и вот простой модульный тест для его экспорта и вызова:</p><pre><code> @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); } </code></pre><p>все это основано на использовании небольшой библиотеки утилит из spf4j ( <a href="http://www.spf4j.org">http://www.spf4j.org</a> )</p><p>вы можете увидеть этот код <a href="https://github.com/zolyfarkas/spf4j/blob/master/spf4j-core/src/main/java/org/spf4j/base/runtime.java#l669">at</a> и тест <a href="https://github.com/zolyfarkas/spf4j/blob/master/spf4j-core/src/test/java/org/spf4j/jmx/registrytest.java#l263">at</a> </p>