2013-09-25 9 views
8

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?

+0

Ich würde wahrscheinlich verwenden, um ein einziges Glas zu bauen - http://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html. –

+0

Haben Sie versucht, Ihren Hauptklassenlader 'addUrl' hinzuzufügen, dann laden Sie die Klasse normal? – assylias

+0

@PaulGrime Die Lizenzierung erlaubt uns leider nur, die verschachtelten JAR-Dateien neu zu verteilen, aber nicht zu entpacken/neu zu packen. –

Antwort

0

AFAIK der Vanille URLClassloader kann nicht damit umgehen.

Bis jetzt ist dies Ihre Antwort.

Abgesehen von Ihrer Lösung gibt es zwei weitere Möglichkeiten, die ich bin mir dessen bewusst:

  1. erstellen Fett jar (p.ex. mit Maven Shade)
  2. eine benutzerdefinierte Classloader erstellen, aber dies ist eine Art von harter Arbeit.
Verwandte Themen