ClassLoader の階層とカスタムローダー
ブートストラップ、プラットフォーム、アプリケーションのクラスローダーを理解し、カスタム ClassLoader を作成します。
「ClassLoader の階層とカスタムローダー」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
ClassLoaderの階層
JVM は ClassLoader の階層を使用します。各ローダーには親があり、クラスを自分でロードする前に親へ委譲します(親優先委譲モデル)。
Bootstrap ClassLoader
Bootstrap ClassLoader はコア JDK クラス(java.lang.*、java.util.*)をロードします。これはネイティブコードで実装され、Java の親を持たないため、getParent() は null を返します。
ClassLoader cl = String.class.getClassLoader();
System.out.println(cl); // null (bootstrap ClassLoader)Platform ClassLoader(Java 9以降)
Platform ClassLoader(旧称 Extension ClassLoader)は、Bootstrap ClassLoader の対象に含まれない JDK のモジュール(java.sql、java.xml など)をロードします。親は Bootstrap ClassLoader です。
ClassLoader platform = ClassLoader.getPlatformClassLoader();
System.out.println(platform.getClass().getName());
// jdk.internal.loader.ClassLoaders$PlatformClassLoaderApplication(System)ClassLoader
Application ClassLoader は、クラスパス(-cp / CLASSPATH)からアプリケーションのクラスをロードします。親は Platform ClassLoader です。ユーザーコードに対するデフォルトのローダーです。
ClassLoader app = ClassLoader.getSystemClassLoader();
System.out.println(app.getClass().getName());
// jdk.internal.loader.ClassLoaders$AppClassLoader親優先委譲
com.example.MyService をロードするとき、AppClassLoader はまず親(Platform)に依頼し、Platform は Bootstrap に依頼します。どの親もロードできない場合に限り、子が自分でロードを試みます。
クラスの同一性とClassLoader
同じ名前を持つクラスでも、異なる ClassLoader によってロードされた場合は別の型とみなされます。それらの間でキャストすると ClassCastException がスローされます。これはプラグインシステムや OSGi で重要です。
// Loaded by two different loaders → different Class objects
Class<?> c1 = loader1.loadClass("com.example.Plugin");
Class<?> c2 = loader2.loadClass("com.example.Plugin");
System.out.println(c1 == c2); // false!カスタムClassLoaderの作成
ClassLoader を継承し、findClass(String name) をオーバーライドします。カスタムのソース(暗号化された JAR、ネットワーク、データベース)からバイトコードを読み込み、defineClass を呼び出します。
public class EncryptedClassLoader extends ClassLoader {
public EncryptedClassLoader(ClassLoader parent) { super(parent); }
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] bytes = decrypt(readBytecodeFromVault(name));
return defineClass(name, bytes, 0, bytes.length);
}
}URLClassLoader: JARからのロード
URLClassLoader は、URL のリスト(ファイルパスまたは HTTP URL)からクラスをロードします。実行時に JAR を追加するプラグインシステムで便利です。
URL[] urls = { new File("plugins/my-plugin.jar").toURI().toURL() };
try (URLClassLoader loader = new URLClassLoader(urls, getClass().getClassLoader())) {
Class<?> cls = loader.loadClass("com.example.PluginImpl");
Plugin plugin = (Plugin) cls.getDeclaredConstructor().newInstance();
plugin.start();
}ClassLoaderを閉じる
完了したら必ず URLClassLoader を閉じてください。JAR が開いたまま保持されるためです。閉じることで、JAR を削除または更新できるようになります。try-with-resources を使用してください。
子優先委譲(分離ロード)
一部のコンテナ(Tomcat、Spring Boot の fat JAR)では階層の順序を逆にし、子ローダーが最初に試行します。見つからない場合のみ親にフォールバックします。これにより、Web アプリケーション間でライブラリのバージョンを分離できます。
ClassLoaderリーク
ClassLoader は、その ClassLoader がロードしたクラスがどれも到達可能でなくなった場合にのみ GC の対象になります。ロードされたクラスのオブジェクトを保持する static フィールドがローダーを生存させ続けます。これは再デプロイ時によくあるリークです。
確認問題
ClassLoader は、クラス自体のロードを試みる前に何をしますか?
まとめ
3階層の構成: Bootstrap → Platform → Application です。親優先委譲によってクラスの重複を防ぎます。カスタムローダーでは findClass をオーバーライドします。プラグインシステムには URLClassLoader を使用します。リークを防ぐため、ローダーを閉じてください。
よくある質問
「ClassLoader の階層とカスタムローダー」レッスンは無料ですか?
はい。「ClassLoader の階層とカスタムローダー」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「ClassLoader の階層とカスタムローダー」で何を学びますか?
ブートストラップ、プラットフォーム、アプリケーションのクラスローダーを理解し、カスタム ClassLoader を作成します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「ClassLoader の階層とカスタムローダー」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- クラスロードの段階:ロード、リンク、初期化
- ClassLoader の階層とカスタムローダー
- javapでバイトコードを調べる
- JITコンパイルと階層型コンパイル