クラスをロードしようとしたときに 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 のサイズと幅と高さのブラウザ解釈の違いに対する解決策
目次MySQL の 4 つの分離レベルデータ テーブルを作成します。分離レベルの設定物事の分離レベル...
navicatを使用してテストと学習を行います。まず、 set autocommit = 0;を使用...
モバイル アプリを開発する場合、Web サイトが特定の高さまでスクロールしたときにコンテンツの一部を...
目次1. データベースのマスター/スレーブ分類: 2. MySQL マスタースレーブの紹介3. マス...
目次1. はじめに2. 行き詰まった問題の分析3. 解決策(理論) 4. ソリューション(コード) ...
目次1. イベントの流れ1. コンセプト2. DOMイベントフロー2. イベントの委任1. イベント...
問題の説明最近、仕事中に問題が発生しました。MySQL が起動に失敗しました。エラー ログは次のとお...
目次1. 値を入力し、そのデータ型を返す** 2. アレイ重複排除3. 文字列の重複排除4. ディー...
Windows インストール mysql-5.7.17-winx64.zip メソッド レコード &...
目次序文1. Props、$emit一方向データフロー2. $親、$子3. $attrs、$list...
一般的な Dockerfile 命令の紹介命令説明するから新しいイメージが構築される基となるイメージ...
この記事では、シームレスなスクロールを実現するためのフレックスレイアウトのサンプルコードを主に紹介し...
目次1. JSONPとは何か2. JSONPクロスドメインリクエスト3. Baidu検索をシミュレー...
日常の開発タスクでは、データ テーブル内のグループ化フィールドに基づいて統計データを取得するために、...
平行ボックスの余白 (二重余白の重なり) に関する面接の質問: 1 つのボックスに上余白があり、もう...