Ich habe das Maven-Shade-Plugin gefunden, das in der pom.xml von jemandem verwendet wird. Ich habe noch nie ein Maven-Shade-Plugin verwendet (und ich bin ein Maven n00b), also habe ich versucht, den Grund für die Verwendung und die Funktionsweise zu verstehen.
Ich habe mir die Maven-Dokumente angesehen , kann diese Aussage jedoch nicht verstehen:
"Dieses Plugin bietet die Möglichkeit, das Artefakt einschließlich seiner Abhängigkeiten in ein Uber-JAR zu packen und die Pakete einiger Abhängigkeiten zu schattieren - dh umzubenennen."
Die Dokumentation auf der Seite scheint nicht sehr für Neulinge geeignet zu sein.
Was ist ein "Überglas"? Warum sollte jemand einen machen wollen? Was bringt es, die Pakete der Abhängigkeiten umzubenennen? Ich habe versucht, die Beispiele auf der Apache-Seite des Maven-Shade-Plugins wie "Auswählen von Inhalten für Uber Jar" durchzugehen, aber ich kann immer noch nicht verstehen, was mit "Shading" erreicht wird.
Hinweise auf veranschaulichende Beispiele / Anwendungsfälle (mit einer Erklärung, warum in diesem Fall eine Schattierung erforderlich war - welches Problem wird gelöst) sind willkommen. Wann sollte ich das Maven-Shade-Plugin verwenden?
quelle
s/reallocation/relocation/
im obigen Kommentar.Antworten:
Kurz gesagt, Uber JAR ist ein JAR, das alles enthält.
Normalerweise verlassen wir uns in Maven auf das Abhängigkeitsmanagement. Ein Artefakt enthält nur die Klassen / Ressourcen von sich. Maven ist dafür verantwortlich, alle Artefakte (JARs usw.) des Projekts herauszufinden, je nachdem, wann das Projekt erstellt wird.
Ein Uber-Jar ist etwas, das alle Abhängigkeiten aufnimmt, den Inhalt der Abhängigkeiten extrahiert und sie mit den Klassen / Ressourcen des Projekts selbst in einer großen JAR zusammenfasst. Mit einem solchen Uber-Jar ist die Ausführung einfach, da Sie nur eine große JAR anstelle von Tonnen kleiner JARs benötigen, um Ihre App auszuführen. In einigen Fällen erleichtert es auch die Verteilung.
Nur eine Randnotiz. Vermeiden Sie die Verwendung von Uber-Jar als Maven-Abhängigkeit, da dies die Funktion zur Auflösung von Abhängigkeiten von Maven ruiniert. Normalerweise erstellen wir uber-jar nur für das endgültige Artefakt für die tatsächliche Bereitstellung oder für die manuelle Verteilung, nicht jedoch für das Maven-Repository.
Update: Ich habe gerade festgestellt, dass ich einen Teil der Frage nicht beantwortet habe: "Was bringt es, die Pakete der Abhängigkeiten umzubenennen?". Hier sind einige kurze Updates, die hoffentlich Menschen mit ähnlichen Fragen helfen werden.
Das Erstellen von Uber-Jar für eine einfache Bereitstellung ist ein Anwendungsfall des Shadow-Plugins. Es gibt auch andere häufige Anwendungsfälle, bei denen Pakete umbenannt werden.
Zum Beispiel entwickle ich eine
Foo
Bibliothek, die von einer bestimmten Version (z. B. 1.0) derBar
Bibliothek abhängt . Angenommen, ich kann keine andere Version vonBar
lib verwenden (aufgrund von API-Änderungen oder anderen technischen Problemen usw.). Wenn ich einfach erklären ,Bar:1.0
wieFoo
‚s Abhängigkeit in Maven ist es möglich , ein Problem zu fallen: EinQux
Projekt wird in Abhängigkeit vonFoo
, und auchBar:2.0
(und es kann nicht verwendet werden,Bar:1.0
weilQux
Bedürfnisse in neue Funktion nutzen zu könnenBar:2.0
). Hier ist das Dilemma: sollteQux
verwendenBar:1.0
(welcherQux
Code wird nicht funktionieren) oderBar:2.0
(welcherFoo
Code wird nicht funktionieren)?Um dieses Problem zu lösen, kann der Entwickler von
Foo
das Schatten-Plugin verwenden, um seine Verwendung von umzubenennenBar
, sodass alle Klassen inBar:1.0
jar in jar eingebettetFoo
sind und das Paket der eingebettetenBar
Klassen voncom.bar
auf geändert wirdcom.foo.bar
. Auf diese Weise kannQux
can sicher davon abhängen,Bar:2.0
da jetztFoo
nicht mehr davon abhängigBar
ist und eine eigene Kopie von "geändert"Bar
in einem anderen Paket verwendet wird.quelle
jar-with-dependency
Deskriptor verwenden. Für das Problem der Abhängigkeits-Roslution mit Uber-Jar habe ich bereits in meiner Antwort erwähnt: Verwenden Sie Uber-Jar nicht als Abhängigkeit, Punkt. Ein bisschen detaillierter: Bevor Sie das Uber-Jar erstellen, sollten Sie ein normales Projekt mit normaler Abhängigkeit haben. Dieses ursprüngliche Artefakt ist dasjenige, das Sie als Abhängigkeit verwenden sollten (anstelle des Überglases)Class.forName
arbeiten?Ich habe mich kürzlich gefragt, warum elasticsearch einige (aber nicht alle) seiner Abhängigkeiten schattiert und verlagert. Hier ist eine Erklärung des Projektbetreuers @kimchy :
- https://github.com/elasticsearch/elasticsearch/issues/2091#issuecomment-7156766
Und noch eine hier von drawr :
- https://github.com/elasticsearch/elasticsearch/pull/3244#issuecomment-20125452
Das ist also ein Anwendungsfall. Als anschauliches Beispiel sehen Sie unten, wie das Maven-Shade-Plugin in der pom.xml (v0.90.5) von elasticsearch verwendet wird. In den
artifactSet::include
Zeilen wird angegeben, welche Abhängigkeiten in die über JAR gezogen werden sollen (im Grunde werden sie entpackt und zusammen mit den eigenen Klassen von elasticsearch neu gepackt, wenn das Ziel-Elasticsearch-JAR erstellt wird. (Falls Sie dies noch nicht wussten, handelt es sich um eine JAR-Datei Nur eine ZIP-Datei, die die Klassen, Ressourcen usw. des Programms und einige Metadaten enthält. Sie können eine extrahieren, um zu sehen, wie sie zusammengesetzt ist.)Die
relocations::relocation
Zeilen sind ähnlich, außer dass sie in jedem Fall auch die angegebenen Ersetzungen auf die Klassen der Abhängigkeit anwenden - in diesem Fall bringen sie sie unterorg.elasticsearch.common
.Schließlich
filters
schließt der Abschnitt einige Dinge aus der Ziel-JAR aus, die nicht vorhanden sein sollten - wie JAR-Metadaten, Ant-Build-Dateien, Textdateien usw., die mit einigen Abhängigkeiten gepackt sind, aber nicht zu einer übergeordneten JAR gehören.quelle
Kleine Warnung
Obwohl das nicht beschreibt, warum man das Maven-Shade-Plugin verwenden möchte (da die ausgewählte Antwort es ziemlich gut beschreibt), möchte ich darauf hinweisen, dass ich Probleme damit hatte. Es hat die JAR geändert (seitdem das, was es tut) und es hat eine Regression in meiner Software verursacht.
Anstatt dieses (oder das Maven-Jarjar-Plugin) zu verwenden, habe ich JarJars Binärdatei verwendet, die problemlos zu funktionieren scheint.
Ich poste hier meine Lösung, da ich einige Zeit gebraucht habe, um eine anständige Lösung zu finden.
Laden Sie die JAR-Datei von JarJar herunter
Sie können das Glas hier herunterladen: https://code.google.com/p/jarjar/ Im linken Menü haben Sie einen Link zum Herunterladen.
Verwendung von JarJar zum Verschieben von Klassen einer JAR von einem Paket in ein anderes
In diesem Beispiel ändern wir das Paket von "com.fasterxml.jackson" in "io.kuku.dependencies.com.fasterxml.jackson". - Die Quell-JAR heißt "jackson-database-2.6.4.jar" und die neue modifizierte (Ziel-) JAR heißt "kuku-jackson-database-2.6.4.jar". - Die JAR-Datei "jarjar" befindet sich in Version 1.4
Erstellen Sie eine "rules.txt" -Datei. Der Inhalt der Datei sollte sein (beachten Sie den Punkt vor dem '@'): Regel com.fasterxml.jackson. ** io.kuku.dependencies.com.fasterxml.jackson. @ 1
Führen Sie den folgenden Befehl aus: java -jar jarjar-1.4.jar process rules.txt jackson-database-2.6.4.jar kuku-jackson-database-2.6.4.jar
Installieren der geänderten JARs im lokalen Repository
In diesem Fall installiere ich 3 Dateien im Ordner "c: \ my-jars \".
mvn install: install-file -Dfile = C: \ my-jars \ kuku-jackson-annotations-2.6.4.jar -DgroupId = io.kuku.dependencies -DartifactId = kuku-jackson-annotations -Dversion = 2.6.4 - Verpackung = Glas
mvn install: install-file -Dfile = C: \ my-jars \ kuku-jackson-core-2.6.4.jar -DgroupId = io.kuku.dependencies -DartifactId = kuku-jackson-core -Dversion = 2.6.4 - Verpackung = Glas
mvn install: install-file -Dfile = C: \ my-jars \ kuku-jackson-database-2.6.4.jar -DgroupId = io.kuku.dependencies -DartifactId = kuku-jackson-annotations -Dversion = 2.6.4 - Verpackung = Glas
Verwenden der geänderten JARs im POM des Projekts
In diesem Beispiel ist dies das Element "Abhängigkeiten" im Projekt pom:
quelle
Ich denke, ein Beispiel für die Notwendigkeit eines "schattierten" Glases ist eine AWS Lambda-Funktion. Sie scheinen nur 1 Glas hochladen zu lassen, nicht eine ganze Sammlung von .jars, wie Sie sie in einer typischen .war-Datei finden würden. Wenn Sie also eine einzelne JAR-Datei mit allen Abhängigkeiten des Projekts erstellen, können Sie dies tun.
quelle