- PR -

独自クラスローダで外部 Jar に含まれるクラスを使用するには?

投稿者投稿内容
まさ
ベテラン
会議室デビュー日: 2002/11/15
投稿数: 74
投稿日時: 2005-04-25 19:46
まさです。

JRE 1.4 以降を使用したアプリケーションを作っています。

アプリケーションからファイル(1)を読み込み、
そのファイルに記述されている Jar ファイル(2) とクラス名を使用して
アプリケーションで用意している URLClassLoader(3) で
2 内のクラス(4) をインスタンス化します。

このとき、単純に 4 のクラスならインスタンス化できるのですが、
その 4 のクラス内から 2 の Jar に含まれる他のクラスを
インスタンス化(リフレクトを使ってインスタンス化かも)しようとすると
デフォルトのクラスローダを使用するらしく、
ClassNotFoundException となってしまいます。

2 の Jar ファイルは外部から提供されているものであり、
ソースを編集することはできません。

何かよい解決策はありますでしょうか?
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-04-25 19:58
現在のソースが、
コード:
URL[] hogeURL = xxxx;
new URLClassLoader(hogeURL);


というような感じでしょうか?

それなら、親クラスローダを引数にして、
コード:
URL[] hogeURL = xxxx;
new URLClassLoader(hogeURL,Thread.currentThread().getContextClassLoader());


とやるとうまく行くような気がします。

クラスファイルはパッケージという名前空間がありますが、
さらにクラスローダという上位の名前空間(名前ではないですが)がありますので、
同じクラスでもクラスローダが違うと別クラスとして扱われます。
ぽん
大ベテラン
会議室デビュー日: 2003/05/13
投稿数: 157
投稿日時: 2005-04-25 23:50
既存のプログラムと(2)を全てクラスパスに通してからプログラムを起動させれば出来ます。
つまり、動的にクラスパスを生成してから既存プログラムを起動させる訳です。

---起動プログラム処理---
Runtime.getRuntime().exec("java -cp \\"既存.jar;(2).jar;・・・\\" MainClass");
-----------------------
まさ
ベテラン
会議室デビュー日: 2002/11/15
投稿数: 74
投稿日時: 2005-04-26 08:23
レスありがとうございます。

引用:

つまり、動的にクラスパスを生成してから既存プログラムを起動させる訳です。


そうですね。これも1つの方法か。
ただ、同一プロセス内で動かしたいのです。
イメージ的には、アプリケーションに対するプラグイン機能を
アプリケーション自体が外部から読み込んで使用したいと。

引用:

コード:
URL[] hogeURL = xxxx;
new URLClassLoader(hogeURL,Thread.currentThread().getContextClassLoader());




なるほど、こうやってクラスローダを関連付ければいいのですね。
試してみます。
ぽん
大ベテラン
会議室デビュー日: 2003/05/13
投稿数: 157
投稿日時: 2005-04-26 10:02
引用:

そうですね。これも1つの方法か。
ただ、同一プロセス内で動かしたいのです。
イメージ的には、アプリケーションに対するプラグイン機能を
アプリケーション自体が外部から読み込んで使用したいと。


起動専用のプログラムと既存プログラムが同一プロセスでなければならないのですか?
(勘違いしてませんか?)

まぁこの方法だとプログラム起動後にjarの追加は出来ませんが。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-04-26 10:39
ファイル選択ダイアログ等でjarファイルを選択して、
動的にクラスをロードするというのはよくある(?)話です。
むしろ別プロセスで起動する方が不自然ではないでしょうか。
(クラスパスの通っていないJDBCドライバのjarファイルを
複数取り込んで実行する実装など・・・)
ぽん
大ベテラン
会議室デビュー日: 2003/05/13
投稿数: 157
投稿日時: 2005-04-26 11:29
引用:

かつのりさんの書き込み (2005-04-26 10:39) より:
ファイル選択ダイアログ等でjarファイルを選択して、
動的にクラスをロードするというのはよくある(?)話です。
むしろ別プロセスで起動する方が不自然ではないでしょうか。
(クラスパスの通っていないJDBCドライバのjarファイルを
複数取り込んで実行する実装など・・・)


仰りたい事はわかります。
しかし、私の方法だと下記の問題が発生しません。
引用:

クラスファイルはパッケージという名前空間がありますが、
さらにクラスローダという上位の名前空間(名前ではないですが)がありますので、
同じクラスでもクラスローダが違うと別クラスとして扱われます。



何より一番単純だと思います
[修正]
簡単→単純

[ メッセージ編集済み 編集者: ぽん 編集日時 2005-04-26 11:40 ]
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2005-04-26 11:38
[蛇足]
JDK5.0 java.lang.instrumentを使うとか…

スキルアップ/キャリアアップ(JOB@IT)