他の 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 oneとthis 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 に渡された文字列) に対して何かを行う必要がありますか?