クラスローダ

■what it is?
クラスをロードするのに使うもの。
@JVM
複数のクラスローダを使い分ける。
@J2EEコンテナ
複数のクラスローダが階層的に追加定義している。
※ユーザが独自定義も可。
☆親子関係がある!!
(親は子を知らないが、子は親を知る。⇒ロードの順番次第でロードエラー)

■what does it do?
*セキュリティサンドボックス やクラスの発見
*インスタンスと参照の管理
*同一性/等価性の評価

■its 親子関係(階層構造)
J2EE コンテナでは、コンテナ製品ごとにクラスローダの階層関係が異なる。
※バージョンによっても変化があり。

■basic working
THREE CLASSLOADER @J2SE
*ブートストラップクラスローダ(初期クラスローダ):
 コアパッケージなど (rt.jar, i18n.jar) のクラスローダ
*拡張クラスローダ:
 拡張機能機能のインストール型オプションパッケージ (lib/ext) のクラスローダ
*ユーザ定義クラスローダ(システムクラスローダ、アプリケーションクラスローダ)

■working order
1. クラスローダがクラスのロードを依頼される: loadClass()
2. 既にロードされていないか調べる
3. 無い場合は、親クラスローダ(無い場合はブートストラップクラスローダ)に処理を委譲(delegation)する
4. ロードされていなければ探してロードしようとする: findClass()

■ブートストラップクラスローダ
コアパッケージなどをロードするクラスローダ。
親は持たない。

■ユーザ定義クラスローダ
ブート時に起動するシステムクラスローダが親。
ex
J2EEコンテナの場合:
EARのユーティリティJAR をロードするクラスローダは、
WARのウェブ・コンポーネントをロードするクラスローダとなっているため、
ウェブ・コンポーネントはEARのユーティリ ティJARを呼ぶことができる。
が、
EARのユーティリティJARは、子であるWAR内のウェブコンポーネントを呼べない。

★staticフィールドは、クラスのロード時に一回実行されるので、クラスローダ内で一つだけ。
→クラスローダをまとめることで、ユーティリティクラスを共通クラスにできるが、要注意。

クラスローダは、抽象クラス java.lang.ClassLoader の派生クラス。
ex
コア・パッケージ内では、
java.security.SecureClassLoader や java.net.URLClassLoader が、
この java.lang.ClassLoader の派生クラスとして定義されている。

■SAMPLE
to get classloader:
//--------------------------------------------------
import test.ExtensionsClass;

class GetClassLoader {
public static void main(String[] args) {
// Bootstrap class loader
System.out.println("□□ブートストラップ・クラスローダ□□");
ClassLoader bootstrap = "".getClass().getClassLoader();
System.out.println(bootstrap);
if (bootstrap != null) {
ClassLoader parent = bootstrap.getParent();
System.out.println(parent);
} else {
System.out.println("親なし");
}
// 拡張クラスローダ
System.out.println("□□拡張クラスローダ□□");
ExtensionsClass extObj = new ExtensionsClass();
ClassLoader extensions = extObj.getClass().getClassLoader();
System.out.println(extensions);
if (extensions != null) {
ClassLoader parent = extensions.getParent();
System.out.println(parent);
} else {
System.out.println("親なし");
}
// システム・クラスローダ
System.out.println("□□システム・クラスローダ□□");
DemoClass myObj = new DemoClass();
ClassLoader systems = myObj.getClass().getClassLoader();
System.out.println(systems);
if (systems != null) {
ClassLoader parent = systems.getParent();
System.out.println(parent);
} else {
System.out.println("親なし");
}
// コンテキスト・クラスローダ
System.out.println("□□コンテキスト・クラスローダ□□");
ClassLoader threads = Thread.currentThread().getContextClassLoader();
System.out.println(threads);
if (threads != null) {
ClassLoader parent = threads.getParent();
System.out.println(parent);
} else {
System.out.println("親なし");
}
}
}

// テスト用クラス
class DemoClass {
String getClassName() {
return "DemoClass";
}
}
--------------------------------------------------//

拡張機能機構のインストール型オプションパッケージの作成:
//--------------------------------------------------
C:\Program Files\Java\jre1.5.0_01\lib\ext>jar -cvf test.jar ./test
マニフェストが追加されました。
test/ を追加中です。(入 = 0) (出 = 0)(0% 格納されました)
test/ExtensionsClass.class を追加中です。(入 = 316) (出 = 225)(28% 収縮されまし
た)
test/ExtensionsClass.java を追加中です。(入 = 120) (出 = 93)(22% 収縮されました)


C:\Program Files\Java\jre1.5.0_01\lib\ext>xcopy /vckyo test.jar C:\Progra~1\Java
\jdk1.5.0_01\jre\lib\ext\test.jar
C:test.jar
1 個のファイルをコピーしました
--------------------------------------------------//
※JRE と JDK では使用するクラスパスが異なるので、両方にコピー。

コンパイルと実行:
//--------------------------------------------------
C:\java>javac GetClassLoader.java

C:\java>java GetClassLoader
□□ブートストラップ・クラスローダ□□
null
親なし
□□拡張クラスローダ□□
sun.misc.Launcher$ExtClassLoader@35ce36
null
□□システム・クラスローダ□□
sun.misc.Launcher$AppClassLoader@11b86e7
sun.misc.Launcher$ExtClassLoader@35ce36
□□コンテキスト・クラスローダ□□
sun.misc.Launcher$AppClassLoader@11b86e7
sun.misc.Launcher$ExtClassLoader@35ce36
--------------------------------------------------//


ref:
浅煎り珈琲
http://www.nextindex.net/java/classloader.html
2007-12-27 00:02 : __lang__java : コメント : 0 : トラックバック : 0 :
コメントの投稿
非公開コメント

« next  ホーム  prev »

search

ad



counter


tag cloud

category cloud