2

状況:

アルゴリズムの時間計算量をプロットするためのシミュレーターを作成しています。学生は、独自の .java ファイルを追加ロードして実行できます。私のプログラムは ('JavaCompiler' で) .java ファイルをコンパイルします。次に、.class ファイルをロードしようとします。

loadedClass = loadClass("customAlgorithms."+this.getClassName()+"");

私のプログラムを Eclipse で実行すると、すべてが正常に動作し、学生はプログラムを問題なく使用できます。

問題:

しかし、その後、プロジェクトを実行可能な jar ファイルにエクスポートします。コンパイル部分は引き続き機能しますが、jar ファイルでクラスを検索するため、クラスのロードは失敗します。

なぜこれができないのだろうと思っていました: (変更 . with /)

loadedClass = loadClass("customAlgorithms/"+this.getClassName()+"");

どのようなオプションが可能ですか? ここで私が考えることができるもの:

  • コンパイルされた .class ファイルを現在実行中の .jar ファイルに追加します。これでも機能しますか?

    jar アーカイブを編集できることは知っています。しかし、これは実行中にプログラムを再起動せずに機能しますか?

  • 「loadClass()」を使用する他の方法はありますか? 私のjarファイルに含まれていないクラスファイルをロードできるように

他のアイデアはありますか?

4

3 に答える 3

3

Java は ClassLoader を介してクラスをロードします。JVM を開始するときは、JVM にその「クラスパス」を伝える必要があります。これは、クラスが存在するフォルダーまたは jar ファイルのリストです。JVM は ClassLoader (通常は URLClassLoader のサブクラス) を作成し、この ClassLoader にフォルダーと jar ファイルのリストを提供して、クラスローダーがクラスをロードできるようにします。

アプリケーションで Java ソース ファイルをコンパイルすると、クラス ファイルが生成され、どこかに保存されます。おそらくEclipseでは、JVMがクラスを見つけることができるように、クラスファイルが保存されるフォルダーはクラスパスに含まれるフォルダーです。

プロジェクトを実行中の jar ファイルにエクスポートすると、おそらく JVM はクラスパスにその JAR ファイルのみを持って開始されるため、コンパイルされたクラスを他の場所で検索することはありません。

これを修正するにはいくつかの方法があります。複雑さの昇順:

  1. jar を実行可能 jar としてではなく、クラスパスの構成を可能にする .bat/.sh またはその他の Java ランナーを使用して、特定のフォルダーをクラスパスに追加し、Java ソース ファイルをそのフォルダーにコンパイルします。
  2. Java ファイルをコンパイルするときに、フォルダーを作成し、そのフォルダーを指す URLClassLoader の新しいインスタンスを作成します。Java ファイルをそのフォルダーにコンパイルします。次に、その URLCLassLoader を使用して、コンパイルされたクラスをロードします。
  3. Java ソースを RAM、たとえばバイト配列にコンパイルし、ディスクからロードする代わりにそのバイト配列を返すカスタム クラスローダーを実装します。

解決策 1 は非常に単純ですが、欠点があります。プログラム全体を再度実行しないと、コンパイル済みの Java ファイルを再ロードできません (一度クラスがクラスローダーにロードされると、再度ロードすることはできません。この質問の範囲外)、プログラムがディスクに書き込む必要があります。これは、アクセス許可などを意味します..

解決策 2 と RAM のみであるその進化は、はるかに洗練されていますが、はるかに複雑です。アプリケーション全体の残りの部分で使用されるものとは異なるクラスローダーから単一のクラスをロードするのは難しいです。奇妙なクラス例外 (ClassCastExceptions など) が発生する可能性があります。 、ClassNotFoundException など..) クラスローダ間の不一致が原因です。

于 2011-08-31T10:55:46.363 に答える
1

ClassLoader defineClass メソッドを使用できます。保護されていますが、問題ないはずです。

メソッドが保護されているという事実が問題である場合は、おそらくインターネットのどこかで、その機能を自由に利用できるカスタム サブクラスを定義できます。

于 2011-08-31T10:49:25.927 に答える
1

URLClassLoader などの別のクラス ローダーを作成し、そこからクラスをロードする必要があります。

于 2011-08-31T10:50:14.117 に答える