3

JVM の複数のインスタンス間で (ネットワーク経由で) 動的に生成された型 (Kryo でシリアル化されたバイナリ表現) を渡す必要がある機能を実装しています。ロードされているタイプとロードされていないタイプを適切に解決するために、カスタム システム クラス ローダー (Java-Djava.system.class.loaderパラメータとして渡される) を使用します。これは、動的に作成された他のクラス ローダーによって親として使用されます。このカスタム システム クラス ローダーはその子を認識しており、クラスが見つからない場合は、これらの派生クラス ローダーにそれがあるかどうかを問い合わせることができます (これは、クラス ローダーの標準的な階層構造とは逆です)。

これらの動的に生成された型は、異なる JVM 間で完全に正常に転送およびロードされます。動的に生成された型の 1 つを参照する何らかの型 (対応するクラスはディスクからロードされ、すべての JMV で同一です) のインスタンスを逆シリアル化しようとすると、問題が発生します。readClass動的に生成された型の名前によって。

メソッド内readClassに への呼び出しがありますClass.forName。これは、指定されたカスタム クラス ローダー (動的に生成されたすべての型を認識している) を使用せず、代わりに sun.misc.Launcher$AppClassLoader インスタンスを使用します。

説明されている問題を回避するために、すべてのクラスがロードされるように、システム全体のカスタム クラス ローダーを指定することは可能ですか?


アップデート

詳細な分析によりClassLoader.getSystemClassLoader()、指定されたカスタム システム クラス ローダーを実際に返すことが明らかになりました。幸いなことに、Kryo ライブラリは、特にデシリアライズ時にクラスをロードするためのカスタム クラス ローダーの設定をサポートしています。これら 2 つの事実は、説明した問題に対する解決策の基礎を形成しました。

4

1 に答える 1

4

そのクラスローダーを使用してすべてのクラスをロードする必要がある場合、カスタムクラスローダーをどのようにロードしますか?

これを回避する 1 つの方法は、ネイティブ インストルメンテーション エージェントを作成することです。これは、クラスがロードされる前にロードされます。

これを回避する別の方法は、独自のバージョンの AppClassLoader をコンパイルし、それをブート クラス パスの前に置くか、libs/endorsedディレクトリに追加することです。

于 2012-04-20T11:18:47.013 に答える