ModuleClassLoader
JBoss Advent Calendar 2012の12日目のエントリです。JBoss AS7のクラスローディングを行っているJBoss Modulesのクラスローダ、ModuleClassLoaderの実装を見ていきましょう。
ModuleClassLoaderの定義はModuleClassLoader extends ConcurrentClassLoaderとなっており、ConcurrentClassLoader extends SecureClassLoaderとなっています。一般的にクラスローダをちょこっとカスタマイズするときによく利用されるURLClassLoaderもextends SecureClassLoaderです。
ModuleClassLoaderもConcurrentClassLoaderも、ついでに言えばURLClassLoaderもJava 7では全てClassLoader.registerAsParallelCapable()を呼び出している並列クラスローディング対応クラスローダです。
ConcurrentClassLoaderは一回だけ他のConcurrentClassLoaderに移譲することを許容する並列クラスローダの基底実装です。import文にsun.misc.Unsafeがありますが見なかったことにしましょう。
ModuleClassLoader.findClass()はロード対象クラスが既にロード済みかどうかをチェックし、まだの場合はModule.loadModuleClass()を呼び出します。Module.loadModuleClass()ではまずロード対象がシステムモジュールかどうかを判断します。システムモジュールの場合はシステムモジュールからロードして終わりです。そうではない場合はロード対象のパス名(パッケージ名)から該当するLocalLoaderを取得して、ロードします。このLocalLoaderは実際には自モジュールから参照可能なモジュールのModuleClassLoaderを参照しており、定義はModuleClassLoaderに内部クラスとして存在しています。パス名とLocalLoaderのMapはモジュールの依存関係解決フェーズで構築されており、対象モジュールを高速にルックアップすることを可能にしています。実際にクラスをロードするのはModuleClassLoader.loadClassLocal()メソッドで、内部クラスのLocalLoader.loadClassLocal()から呼ばれます。
コールスタック。
- ModuleClassLoader.loadClassLocal()
- 実際のロード処理
- ModuleClassLoader.LocalLoader.loadClassLocal()
- Module.loadModuleClass()
- 対象ModuleClassLoaderをルックアップ
- ModuleClassLoader.findClass()
- ロード済みをチェックしてからModuleに移譲
- ModuleClassLoader.performLoadClassUnChecked()
- ModuleClassLoader.performLoadClassChecked()
- ModuleClassLoader.performLoadClass()
- ModuleClassLoader.loadClass()
- ここからfindClass()まではConcurrentClassLoaderに定義されている
- Class.forName()
ねっ、簡単でしょ?