31

実行時にどのクラスがどの JAR からロードされるかを判断する方法はありますか?

私たちは皆、以前に JAR 地獄にいたことがあると確信しています。私はこの問題に何度も遭遇し、プロジェクトのトラブルシューティングClassNotFoundExceptionやトラブルシューティングを行ってきました。NoClassDefFoundErrorJAR 内のクラスのすべてのインスタンスを検索したり、コードで削除プロセスを使用して CNFE が原因を見つけたりすることは避けたいと思います。

この種の情報を提供するプロファイリングまたは管理ツールはありますか?

この問題は、クラスがロードされるときにこの情報が必要なため、非常に厄介です。そこにたどり着く方法、または記録して見つける方法がなければなりませんが、これを行う方法を私は何も知りませんよね?

OSGi とバージョン管理されたバンドル/モジュールがこれを問題にしないようにすることを目指していることは知っていますが、すぐになくなるわけではないようです。

注: この質問は、バージョン管理された jar からロードされたクラスに関連する私の質問のサブセットであることがわかりました。

多少関連するこの投稿では、JAR 内 (現在のディレクトリの下) または M2_REPO 内でクラスを検索する戦略について説明しています: JarScan、特定のクラスのすべてのサブフォルダー内のすべての JAR ファイルをスキャンします。

また、多少関連するJBoss Tattletale

4

5 に答える 5

59

-verbose:classスイッチをコマンドに渡すと、javaロードされた各クラスとロード元が出力されます。

Joopsは、不足しているクラスを事前に見つけるための優れたツールでもあります。

于 2009-06-03T20:59:35.497 に答える
15

コードから以下を呼び出すことができます:

myObject.getClass().getProtectionDomain().getCodeSource()

(注、getProtectionDomain残念ながら (悪い設計) が返される可能性があるnullため、「適切なコード」がそれをチェックします。)

于 2009-06-03T21:04:19.310 に答える
4

上記のJasonDayが言及したJVMフラグ用のMBeanがあります。

JBossを使用している場合、ネイティブJMX MBeanサーバーを設定に追加すると、JMXを使用してオンデマンドでこれを調整できます。次の-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と呼ばれ、FQCNを渡してdisplayClassInfo()操作を呼び出す必要があります。

于 2010-02-25T21:49:02.770 に答える
0

WebSphere (WAS) では、「Class Loader Viewer」という機能を使用できます。

最初に「サーバー」 > 「サーバー・タイプ」 > 「WebSphere アプリケーション・サーバー」 > 「サーバー名」 > 「クラス・ローダー・ビューアー・サービス」をクリックしてクラス・ローダー・ビューアーを有効にし、サービスを有効にしてサーバーを再始動します。

次に、[トラブルシューティング] > [クラス ローダー ビューアー] に移動して、クラスまたはパッケージ名を検索できます。

https://www-01.ibm.com/support/knowledgecenter/SSAW57_8.5.5/com.ibm.websphere.nd.doc/ae/ttrb_classload_viewer.html?lang=en

于 2016-02-10T20:49:59.057 に答える
0

JMX 操作を簡単にエクスポートして、プロセス内のロードされたクラスのパッケージ情報にアクセスできます。

  public static final class Jmx {

    @JmxExport
    public static Reflections.PackageInfo getPackageInfo(@JmxExport("className") final String className) {
      return Reflections.getPackageInfo(className);
    }
  }

これをエクスポートして呼び出す簡単な単体テストを次に示します。

  @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 )の小さなユーティリティ ライブラリを使用して作成されています。

このコードはで、テストはで見ることができます

于 2016-04-08T14:17:09.547 に答える