クラスをロードしようとしたときに JVM が失敗したことを示す ClassNotFound 例外が頻繁に発生します。 この例外を解決するには、次のことを知っておく必要があります
Tomcat が Web アプリケーションでサーブレットをロードして管理する方法について考えてみましょう。 JVM クラスローダーJava クラスのロードとは、バイトコード形式の .class ファイルを JVM のメソッド領域にロードし、JVM ヒープ内に java.lang.Class オブジェクト インスタンスを作成して、Java クラスに関連するデータとメソッドをカプセル化することです。 クラスオブジェクトとは何ですか? JVM は起動時にすべての .class ファイルをロードするのではなく、プログラムが動作中に使用されるときにのみクラスをロードします。 パブリック抽象クラス ClassLoader { //各クラスローダーには親ローダーがあります private final ClassLoader parent; パブリッククラス<?> loadClass(文字列名) { // クラスがロードされているかどうかを確認します Class<?> c = findLoadedClass(name); // ロードされていない場合 if( c == null ){ // [再帰] 親ローダーにロードを委任する if (parent != null) { クラス名をロードします。 } それ以外 { // 親ローダーが空の場合は、Bootstrap ローダーがロードされているかどうかを確認します c = findBootstrapClassOrNull(name); } } // 親ローダーがロードに失敗した場合は、独自のfindClassを呼び出してロードします。if (c == null) { クラス名を検索します。 } c を返します。 } 保護されたクラス<?> findClass(文字列名){ // 1. 渡されたクラス名に従って、特定のディレクトリ内のクラス ファイルを検索し、.class ファイルをメモリに読み込みます... // 2. defineClass を呼び出してバイト配列を Class オブジェクトに変換します。 return defineClass(buf, off, len); } // バイトコード配列をクラスオブジェクトに解析し、ネイティブメソッドで実装します。protected final Class<?> defineClass(byte[] b, int off, int len){ ... } } JVM のクラス ローダーは階層的な親子関係を持ち、各クラス ローダーは親ローダーを指す親フィールドを保持します。
loadClass は、まずクラスがロードされているかどうかを確認します。ロードされている場合は直接戻り、ロードされていない場合は親ローダーに渡してロードします。 JDK クラス ローダーの動作原理は同じですが、唯一の違いはロード パス、つまり findClass によって検索されるパスが異なります。 クラス ローダーの親子関係は継承を通じて実装されません。たとえば、AppClassLoader は ExtClassLoader のサブクラスではありませんが、AppClassLoader の親は ExtClassLoader オブジェクトを指します。 Tomcat クラスローダーTomcat のカスタム クラス ローダー WebAppClassLoader は親の委任メカニズムを破壊します。 クラスを検索パブリック Class<?> findClass(String name) は ClassNotFoundException をスローします { ... クラス<?> clazz = null; 試す { //1. まず、Web アプリケーション ディレクトリでクラスを検索します。clazz = findClassInternal(name); } キャッチ (RuntimeException e) { eを投げる; } (clazz == null)の場合{ 試す { //2. ローカル ディレクトリで見つからない場合は、親ローダーで検索させます。clazz = super.findClass(name); } キャッチ (RuntimeException e) { eを投げる; } //3. 親クラスが見つからない場合は、ClassNotFoundException をスローします。 (clazz == null)の場合{ 新しい ClassNotFoundException(名前) をスローします。 } 戻りクラッズ; } ワークフロー
ロードクラスパブリック Class<?> loadClass(String name, boolean resolve) は ClassNotFoundException をスローします { 同期化 (getClassLoadingLock(名前)) { クラス<?> clazz = null; //1. まず、ローカル キャッシュでクラスがロードされているかどうかを確認します。clazz = findLoadedClass0(name); (clazz != null)の場合{ もし(解決する) クラスを解決します(clazz); 戻りクラッズ; } //2. システム クラス ローダーがロードされているかどうかを確認します clazz = findLoadedClass(name); (clazz != null)の場合{ もし(解決する) クラスを解決します(clazz); 戻りクラッズ; } // 3. ExtClassLoader クラス ローダーを使用してクラスをロードしようとしますが、なぜでしょうか? クラスローダー javaseLoader = getJavaseClassLoader(); 試す { clazz = javaseLoader.loadClass(名前); (clazz != null)の場合{ もし(解決する) クラスを解決します(clazz); 戻りクラッズ; } } キャッチ (ClassNotFoundException e) { // 無視する } // 4. ローカルディレクトリでクラスを検索してロードしてみる try { clazz = findClass(名前); (clazz != null)の場合{ もし(解決する) クラスを解決します(clazz); 戻りクラッズ; } } キャッチ (ClassNotFoundException e) { // 無視する } // 5. システムクラスローダー(AppClassLoader)を使用してロードを試みる try { clazz = Class.forName(名前、false、親); (clazz != null)の場合{ もし(解決する) クラスを解決します(clazz); 戻りクラッズ; } } キャッチ (ClassNotFoundException e) { // 無視する } } //6. 上記のプロセスはすべてロードに失敗し、例外をスローします。throw new ClassNotFoundException(name); } ワークフロー
Tomcat クラス ローダーは親の委任を破棄し、最初は親ローダーに直接委任せず、最初にローカル ディレクトリにロードすることがわかります。 Tomcat が親委任メカニズムを破壊する仕組みについての記事はこれで終わりです。Tomcat の親委任メカニズムの詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
>>: CSS のサイズと幅と高さのブラウザ解釈の違いに対する解決策
プロジェクトでは、SQL を使用してデータ分析を実行するために、大量のデータをデータベースにインポー...
目次序文静的スコープと動的スコープ静的スコープ実行プロセス動的スコープ実行プロセスエクササイズ練習1...
目次最初の方法: router-link (宣言型ルーティング) 2番目の方法: router.pu...
この記事では、ビデオプレイリストを実装するためのvue + video.jsの具体的なコードを参考ま...
この記事の例では、ページ切り替え効果を実現するためのJSコードの具体的なコードを参考までに共有してい...
この記事では、例を使用して MySQL の重複インデックスと冗長インデックスについて説明します。ご参...
1. nginxシェルスクリプトを保存するフォルダを作成する /usr/local/タスク/ngin...
この記事ではJavaScript検索のデータ表示コードを参考までに共有します。具体的な内容は以下のと...
最近のプロジェクトでは、Google ロボット認証を使用する必要があります。これには VPN が必要...
この記事では、参考までにMySQL 5.7.18 MSIインストールチュートリアルを紹介します。具体...
序文最近、仕事の都合で、APP ショッピングカートの注文支払いに取り組んでいました。テスト中にバグが...
目次導入説明名前の競合私有財産要約する導入シンボル変数を作成する最も簡単な方法は、Symbol() ...
1. シェルスクリプトを作成する vim バックアップdb.sh 次のようにスクリプトを作成します。...
ファイル名が少ないファイルを表示ファイル名を少なく | grep -n コンテンツを検索内容に応じて...
目次MySQL 5.6以前MySQL 5.6以降要約する知らせMySQL 5.6以前更新手順元のテー...