10

他の JAR ファイルを含む場合がある実行可能 JAR ファイルがあります。(全体は、宇宙に展開された巨大なカメの背中に乗って、ダウンロードされた他の 4 つの JAR にかかっています。) 実行時に、次のようにしてネストされた JAR ファイルを動的にロードします。

// wearyingly verbose error handling elided

URL nestedURL = the_main_system_classloader.getResource("path/to/nested.jar");
File temp = File.createTempFile (....);
// copy out nestedURL contents into temp, byte for byte

URL tempURL = temp.toURI().toURL();
URLClassLoader loader = URLClassLoader.newInstance(new URL[]{ tempURL });
Class<?> clazz = loader.loadClass("com.example.foo.bar.baz.Thing");
Thing thing = (Thing) clazz.newInstance();
// do stuff with thing

この種のテクニックは以前ここで取り上げられました。リンクにはthis onethis oneが含まれます。現在配置されているコードは機能します...

...多くの場合。一時ファイルの作成とコピーを回避する方法を見つけたいと思います(そして、最終的にはクリーンアップします。ご存知のように、deleteOnExit は悪です)。結局、開始時に取得された URL は JAR を指しています。

URL nestedURL = the_main_system_classloader.getResource("path/to/nested.jar");
// nestedURL.toString() at this point is
// "jar:file:/C:/full/path/to/the/executable.jar!/path/to/nested.jar"
URLClassLoader loader = URLClassLoader.newInstance(new URL[]{ nestedURL });
Class<?> clazz = loader.loadClass("com.example.foo.bar.baz.Thing");

しかし、loadClass は ClassNotFound をスローします。

URLClassLoader は、この JAR 内の JAR ケースを単純に処理できないのでしょうか? または、これを機能させるために、関連する 1 つ以上のパス (nestedURL または loadClass に渡された文字列) に対して何かを行う必要がありますか?

4

1 に答える 1

1

私の知る限り、バニラの URLClassloader はそれを処理できません。

これまでのところ、これがあなたの答えです。

あなたの解決策とは別に、私が知っている2つの可能性があります。

  1. ファット jar を作成します (p.ex. Maven Shade を使用)
  2. カスタム クラスローダーを作成しますが、これは大変な作業です。
于 2014-06-17T21:22:22.060 に答える