2

この(半疑似)コードを考えてみましょう:

private static final File file = new File("./archive.jar");
private static URLClassLoader classLoader;

public static void main(final String[] args) {
    try {
        classLoader = new URLClassLoader(new URL[] { file.toURI().toURL() });
        Method mainMethod = classLoader.loadClass("main class").getDeclaredMethod("main", String[].class);
        mainMethod.setAccessible(true);
        mainMethod.invoke(null, (Object) new String[] { "-arguments" });
    } catch(Exception e) {
        e.printStackTrace();
    }
}

... そして、Eclipse IDE での次の 2 つのプロジェクト設定:

最初のプロジェクト設定。 2 番目のプロジェクトのセットアップ。

提供されたコードは JAR ファイルから何もインポートしませんが、動作は異なります。どう違うの?まず、最初のプロジェクト設定を使用すると、この Web サイトのテーマでエラーがスローされます。

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
Caused by: java.lang.StackOverflowError
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)

行で発生しているエラー:

mainMethod.invoke(null, (Object) new String[] { "-arguments" });

ただし、2 番目のプロジェクト セットアップ (JAR がビルド パスの一部であるプロジェクト) を使用すると、エラーは発生しません。それに加えて、最初のプロジェクト設定を使用すると、コードが機能しません。正しく動作する場合に何が起こるかはわかっています。最初のプロジェクトのセットアップでは発生しませんが、2 番目のプロジェクトでは発生します。言及する価値のあるもう 1 つのことは、JAR ファイルが Eclipse の Order and Exports のリストの一番上にある場合にのみ、コードが機能することです。

注文とエクスポートのリスト。

なぜそれが起こるのですか?JAR から何もインポートされていない場合、ビルド パスの一部である必要があるのはなぜですか? クラス ローダーは実際のファイルに基づいてこれを使用するため、プロジェクトのビルド パスに関連付けられているかどうかは問題ではありません。

4

1 に答える 1

3

StackOverflowError は通常、呼び出しループを意味します。この場合、たとえばリンクしようとしているクラスが有効かどうかを確認するなど、JVM が必要なものを探し回っている可能性があると思います。

メソッドを実行するにはリンクが必要であり、検証とシンボリック参照の解決が必要です。

ライブラリなしで何がうまくいかないのかをさらに理解するには、メインクラスのコードを見て、それが何を参照しているかを知る必要があります。

Java でのインポートをあまり重要視しないでください。クラス名を完全修飾せずに使用できるようにするだけです: java.util.ArrayList ではなく、ArrayList です。

于 2012-11-05T05:24:23.903 に答える