- - PR -
Jar ファイルからのクラス読み込み処理
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2006-12-12 11:23
この状態で自前のクラスローダでごにょごにょするような プログラムを作るのは自制した方がいいのでは・・・。 JARもURLClassLoaderを使えば自分で読み込む必要はないです。 ClassLoaderのソースを読めばわかることですが、loadClass()系を オーバーライドする主な目的は親ローダとの委譲関係の上書きです。 単にバイトコードの改変が目的ならば、findClass()をオーバーライド する方が無難だと思います。 #現状のコードだとクラスローダの親子関係を考慮していないので、 #このクラスローダからはjava.langパッケージすら解決に失敗します。 ついでに、この構造だとクラスの遅延ロードができないので遅いですよ。 意図的にJAR中の全てのクラスを事前にロードしたいのなら別ですけど。 | ||||
|
投稿日時: 2006-12-12 12:03
私も、クラスローダは自作しないほうがよいと思います。(セキュリティの穴になりそうな気が。)
ただ、プログラムの問題で一応わかることを返信しておきます。 defineClassの前に System.out.println("name=" + name); を入れるとa/Testになっていたので、 String className = name.replace("\\", ".").replaceAll("\\.class", ""); は間違いで String className = name.replace("/", ".").replaceAll("\\.class", ""); でしたね。 単純にjarファイルをそのまま return defineClass(name, bytes, 0, bytes.length); すると Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.lang at java.lang.ClassLoader.preDefineClass(ClassLoader.java:479) となるので、この後を知りたいなら、ClassLoaderをよく知っている人に聞いたほうがよいでしょう。(私は、ClassLoaderを作ったことはない) | ||||
|
投稿日時: 2006-12-12 13:17
>あしゅさん、だっちょさん
URLClassLoaderを使いたいのはやまやまですが、そうなるとjarファイルからクラスを読み込むだけになりますよね? コードからお気づきかと思いますが、この読み込み処理は全体の一部で、読み込んできたバイトコードに他のバイトコードを付け加えて(NotifierClassVisitor)ファイル出力させようと思っているのです。 それだと、URLClassLoaderでは処理できないのではないかと思うのですが・・・。 | ||||
|
投稿日時: 2006-12-12 13:20
クラスローダを自作するのは意外と手間になります。
・パッケージの解決 ・クラスの解決 ・リソースの解決 等を、クラスローダの親子関係を考慮して設計しなければいけないのですが、 多分コンパイルエラーの解決が難しいレベルでは、作れるものではありません。 バイトコード操作といっても、メソッド操作の前後にほにゃらら・・・なら AOPエンジンなどもありますし、もうちょっと勉強されてからの方がいいと思います。 | ||||
|
投稿日時: 2006-12-12 13:25
>かつのりさん
もちろん、もっと勉強してからすべきなのは分かっておりますし、 javaに関して自分の知識が足りなさ過ぎるのも重々承知しております。 しかし、どうしても完成させなければならず、またASMを利用しなければならないという制約の元作っておりますので、こうして質問をするに至ったわけです。 ご理解いただけるとありがたいです。 [ メッセージ編集済み 編集者: ヒラ 編集日時 2006-12-12 13:27 ] | ||||
|
投稿日時: 2006-12-12 13:38
もちろん承知の上です。 URLClassLoader#findClass(String)はfinalではないので、 クラスファイルはfindResource(String)経由でJARから取得して 改変したバイトコードをdefineClass()する作りに上書きできます。 | ||||
|
投稿日時: 2006-12-12 13:45
クラスローダについては、この場で詳しく説明するのが難しいので
以下のリンク先を読んで勉強してみてください。 http://discypus.jp/wiki/?Java%2F%A5%AF%A5%E9%A5%B9%A5%ED%A1%BC%A5%C0%A1%BC からの引用ですが、 クラス・ローディング問題の神秘を解く 第1回: クラス・ローディングとデバッグ・ツール 2005年9月29日 (2006-01-29) http://www-06.ibm.com/jp/developerworks/java/060113/j_j-dclp1.shtml クラス・ローディング問題の神秘を解く 第2回: クラス・ローディングに関する基本的な例外 2005年12月6日 (2006-01-29) http://www-06.ibm.com/jp/developerworks/java/060127/j_j-dclp2.shtml Javaプログラミングのダイナミックス 第1回: クラスとクラスのロード処理 2003年4月29日 http://www-06.ibm.com/jp/developerworks/java/030704/j_j-dyn0429.html Javaプログラミングのダイナミックス 第4回: Javassistでのクラス変換 2003年9月16日 http://www-06.ibm.com/jp/developerworks/java/040206/j_j-dyn0916.html Javaプログラミングのダイナミックス 第5回: オンザフライでクラスを変換する 2004年2月3日 http://www-06.ibm.com/jp/developerworks/java/040326/j_j-dyn0203.html を、じっくり読んでみるといいと思います。 全て読んだ上で分からないところがあれば、また質問してみてください。 ただし、クラスのローディングとコンパイルエラーは別問題なので、 コンパイルエラーくらいは最低限解決出来るようにはしてくださいね。 | ||||
|
投稿日時: 2006-12-12 15:07
URLClassLoaderを使って書き換えてみようと思います。
|