Wir haben eine ausführbare JAR-Datei, die manchmal enthält andere JAR-Dateien. (. Das Ganze auf vier andere heruntergeladen JARs ruht, auf dem Rücken eines riesigen Einsatz Schildkröte im Raum Reiten) zur Laufzeit laden wir dynamisch, die verschachtelte JAR-Datei Sie folgendermaßen vorgehen:Javas Classloader im Vergleich zu Gläsern innerhalb von Gläsern
// 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
Diese Art von Technik hat Ich bin schon früher hier aufgewachsen. Links beinhalten this one und this one. Der Code, den wir derzeit haben, funktioniert ...
... meistens. Ich würde wirklich gerne einen Weg finden, die temporäre Erstellung und das Kopieren von Dateien zu vermeiden (und eventuell eine Bereinigung, denn wie wir alle wissen, deleteOnExit is evil). Die URL direkt an den Startpunkten zu einer JAR erhalten, nachdem alle:
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");
Aber loadclass wirft einen ClassNotFound.
Kann der URLClassLoader diesen JAR-in-a-JAR-Fall nicht verarbeiten? Oder muss ich etwas für einen oder mehrere der beteiligten Pfade tun (entweder die nestedURL oder die an loadClass übergebene Zeichenfolge), damit dies funktioniert?
Ich würde wahrscheinlich verwenden, um ein einziges Glas zu bauen - http://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html. –
Haben Sie versucht, Ihren Hauptklassenlader 'addUrl' hinzuzufügen, dann laden Sie die Klasse normal? – assylias
@PaulGrime Die Lizenzierung erlaubt uns leider nur, die verschachtelten JAR-Dateien neu zu verteilen, aber nicht zu entpacken/neu zu packen. –