Javaの質問です。あるツールを使うとJavaのクラスファイルがいくつか入ったJARが出力されます。しかしそれらのクラスファイルはデフォルト・パッケージに入っています。Java1.4以降ではデフォルト・パッケージからのインポートができなくなったので、このJARをビルドパスに入れても肝心のクラスをインポートして使うことが出来ません。JARファイルを一度解凍して勝手にフォルダを作ってクラスファイルを移動してみたりしたのですが、ClassDefNotFoundErrorになります。クラスファイル自信が持っている「自分がどのパッケージにいるか」という情報と矛盾するからでしょうかね…。


なにか解決方法はあるでしょうか?

回答の条件
  • 1人2回まで
  • 登録:2007/02/02 00:41:51
  • 終了:2007/02/09 00:45:02

回答(2件)

id:b-wind No.1

b-wind回答回数3344ベストアンサー獲得回数4402007/02/02 00:48:30

ポイント35pt

ツールの方で何とかするのが正攻法だと思うけど。

逆コンパイルすると言う手も有る。

http://home.f02.itscom.net/soukyoku/jtips/jad.html]

id:westfish

やっぱりそうですよねぇ。

実はコンパイルされる前の(ツールによって生成された)ソースも手に入るので、それらにパッケージ宣言を付け足してコンパイルしてJARにまとめるツールを作ればいいわけですが…うーむ。

やっぱりコンパイルされてしまったらいじるのは至難ですか。

2007/02/02 01:31:40
id:quintia No.2

quintia回答回数562ベストアンサー獲得回数712007/02/02 09:47:57

ポイント35pt

import に書けないだけで、A.class を classpath がとおったフォルダに置いておけば、Class. forName("A") でデフォルトパッケージのクラスAをClassLoaderに読み込ませることはできます。

Class#newInstance() でのインスタンスの生成もできます。

とここまでは確認済。

それがjarに入っている場合は確認してませんが、classpathが通ってさえいれば同じ様にできるのではないかなあ、と楽観視してます。

で、ここからはアイデア。


頻繁に使わないし頻繁に呼び出されることもないケース

リフレクション経由で使う。


色々な所で使うが頻繁に呼び出されることはないケース

リフレクション経由で呼び出すラッパーを作る。


ほとんど依存していると言ってもいいぐらい使っているケース

名前付きpackage に(アプリ本体とは別の package にした方が依存関係を集約できていいと思う) interface InterfaceA を作って、A のメソッドとフィールド変数のget/setメソッドを定義。

デフォルトパッケージに class WrapperA implements InterfaceA を作って、Aのインスタンスを生成した後、メソッドは全部Aに委譲してしまう様に実装。

名前付きpackageの方にユーティリティメソッド

public static InterfaceA newInstaceA() {
  Class c = Class.forName("WrapperA");
  return (InterfaceA)c.newInstance();
}

の様な感じのメソッドを作っておくとして、本体プログラムは InterfaceA を相手にするように書く。


というような感じにするといいのではないでしょうか。

id:westfish

おおー、なるほど

importができなくても、リフレクションで取得することはできてしまうわけですね!それは気づきませんでした!

2007/02/02 13:04:58

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません