387 Stimmen

Wie kann man JAR-Dateien dynamisch zur Laufzeit laden?

Warum ist es so schwer, dies in Java zu tun? Wenn Sie irgendeine Art von Modulsystem haben wollen, müssen Sie in der Lage sein, JAR-Dateien dynamisch zu laden. Mir wurde gesagt, dass es einen Weg gibt, dies zu tun, indem man seine eigenen ClassLoader aber das ist eine Menge Arbeit für etwas, das (zumindest meiner Meinung nach) so einfach sein sollte wie der Aufruf einer Methode mit einer JAR-Datei als Argument.

Gibt es Vorschläge für einen einfachen Code, der dies ermöglicht?

3voto

Aleksey Punkte 139

Bitte schauen Sie sich dieses Projekt an, das ich begonnen habe: proxy-object lib

Diese Lib lädt jar aus dem Dateisystem oder von einem anderen Ort. Sie wird einen Klassenlader für die Jar-Datei bereitstellen, um sicherzustellen, dass es keine Bibliothekskonflikte gibt. Benutzer können jedes Objekt aus dem geladenen Jar erstellen und jede Methode darauf aufrufen. Diese Bibliothek wurde entwickelt, um Jars zu laden, die in Java 8 aus der Codebasis kompiliert wurden, die Java 7 unterstützt.

Um ein Objekt zu erstellen:

    File libDir = new File("path/to/jar");

    ProxyCallerInterface caller = ObjectBuilder.builder()
            .setClassName("net.proxy.lib.test.LibClass")
            .setArtifact(DirArtifact.builder()
                    .withClazz(ObjectBuilderTest.class)
                    .withVersionInfo(newVersionInfo(libDir))
                    .build())
            .build();
    String version = caller.call("getLibVersion").asString();

ObjectBuilder unterstützt Factory-Methoden, den Aufruf statischer Funktionen und den Rückruf von Schnittstellenimplementierungen. Ich werde weitere Beispiele auf der Readme-Seite veröffentlichen.

3voto

steve212 Punkte 21

Dies kann eine späte Antwort sein, ich kann es so tun (ein einfaches Beispiel für fastutil-8.2.2.jar) mit jhplot.Web-Klasse von DataMelt ( http://jwork.org/dmelt )

import jhplot.Web;
Web.load("http://central.maven.org/maven2/it/unimi/dsi/fastutil/8.2.2/fastutil-8.2.2.jar"); // now you can start using this library

Laut Dokumentation wird diese Datei innerhalb von "lib/user" heruntergeladen und dann dynamisch geladen, so dass Sie sofort mit der Verwendung von Klassen aus dieser jar-Datei im selben Programm beginnen können.

1voto

Bằng Rikimaru Punkte 1273

Ich musste eine Jar-Datei zur Laufzeit sowohl für Java 8 als auch für Java 9+ laden (die obigen Kommentare funktionieren nicht für beide Versionen). Hier ist die Methode, es zu tun (mit Spring Boot 1.5.2, wenn es beziehen kann).

public static synchronized void loadLibrary(java.io.File jar) {
    try {            
        java.net.URL url = jar.toURI().toURL();
        java.lang.reflect.Method method = java.net.URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{java.net.URL.class});
        method.setAccessible(true); /*promote the method to public access*/
        method.invoke(Thread.currentThread().getContextClassLoader(), new Object[]{url});
    } catch (Exception ex) {
        throw new RuntimeException("Cannot load library from jar file '" + jar.getAbsolutePath() + "'. Reason: " + ex.getMessage());
    }
}

1voto

Richard Kotal Punkte 159

Für das dynamische Hochladen von jar-Dateien können Sie meine Modifikation von URLClassLoader verwenden. Diese Modifikation hat kein Problem mit der Änderung der jar-Datei während des Anwendungsbetriebs, wie der Standard-URLClassLoader. Alle geladenen jar-Dateien werden in den Arbeitsspeicher geladen und sind somit unabhängig von der Originaldatei.

In-Memory-Jar und JDBC-Klassenlader

-3voto

tanyehzheng Punkte 2166

Ich persönlich finde, dass java.util.ServiceLoader erfüllt die Aufgabe ziemlich gut. Sie können ein Beispiel erhalten aquí .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X