Ich habe mich vor kurzem gefragt, warum elasticsearch einige (aber nicht alle) seiner Abhängigkeiten abschattet und verlagert. Hier ist eine Erklärung vom Betreuer des Projekts, @kimchy :
Die Schattierung ist beabsichtigt, die schattierten Bibliotheken, die wir in elasticsearch verwenden, sind in jeder Hinsicht Teil von elasticsearch, die verwendete Version ist eng mit dem verknüpft, was elasticsearch offenlegt und wie es die Bibliothek verwendet, basierend auf den Interna, wie die Bibliothek funktioniert (und das ändert sich zwischen den Versionen), netty und guava sind gute Beispiele.
Übrigens habe ich kein Problem damit, mehrere Jars von Elasticsearch zur Verfügung zu stellen, eines mit Lucene ohne Schatten, und eines mit Lucene mit Schatten. Ich bin mir allerdings nicht sicher, wie ich das mit Maven machen soll. Ich möchte keine Version zur Verfügung stellen, die z.B. netty/jackson nicht schattiert, weil elasticsearch sehr eng mit ihnen verbunden ist (z.B. wird die Verwendung der kommenden Pufferring-Verbesserung mit jeder früheren Version von netty, außer der aktuellen, mehr Speicher verbrauchen, als wenn man deutlich weniger verwendet).
-- https://github.com/elasticsearch/elasticsearch/issues/2091#issuecomment-7156766
Und eine weitere hier von drewr :
Die Schattierung ist wichtig, um unsere Abhängigkeiten (insbesondere netty, lucene, guava) in der Nähe unseres Codes zu halten, damit wir ein Problem beheben können, auch wenn der Upstream-Anbieter hinterherhinkt. Es ist möglich, dass wir modularisierte Versionen des Codes verteilen werden, was bei Ihrem speziellen Problem helfen würde (#2091 zum Beispiel), aber wir können die schattierten Abhängigkeiten zu diesem Zeitpunkt nicht einfach entfernen. Sie können eine lokale Version von ES für Ihre Zwecke erstellen, bis es eine bessere Lösung gibt.
-- https://github.com/elasticsearch/elasticsearch/pull/3244#issuecomment-20125452
Das ist also ein Anwendungsfall. Zur Veranschaulichung ein Beispiel, wie das maven-shade-plugin in der pom.xml von elasticsearch (v0.90.5) verwendet wird. Die artifactSet::include
Zeilen weisen es an, welche Abhängigkeiten in das Uber-JAR gezogen werden sollen (im Grunde werden sie entpackt und zusammen mit den elasticsearch-eigenen Klassen neu verpackt, wenn das Ziel-Elasticsearch-Jar erzeugt wird. (Falls Sie es noch nicht wussten, eine JAR-Datei ist einfach eine ZIP-Datei, die die Programmklassen, Ressourcen usw. und einige Metadaten enthält. Sie können eine entpacken, um zu sehen, wie sie zusammengesetzt ist).
En relocations::relocation
Zeilen sind ähnlich, mit dem Unterschied, dass sie in jedem Fall auch die angegebenen Ersetzungen auf die Klassen der Abhängigkeit anwenden - in diesem Fall, indem sie sie unter org.elasticsearch.common
.
Schließlich wird die filters
Abschnitt schließt einige Dinge aus dem Ziel-JAR aus, die dort nicht enthalten sein sollten - wie JAR-Metadaten, Ant-Build-Dateien, Textdateien usw., die mit einigen Abhängigkeiten verpackt sind, aber nicht in ein Uber-JAR gehören.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<minimizeJar>true</minimizeJar>
<artifactSet>
<includes>
<include>com.google.guava:guava</include>
<include>net.sf.trove4j:trove4j</include>
<include>org.mvel:mvel2</include>
<include>com.fasterxml.jackson.core:jackson-core</include>
<include>com.fasterxml.jackson.dataformat:jackson-dataformat-smile</include>
<include>com.fasterxml.jackson.dataformat:jackson-dataformat-yaml</include>
<include>joda-time:joda-time</include>
<include>io.netty:netty</include>
<include>com.ning:compress-lzf</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>org.elasticsearch.common</shadedPattern>
</relocation>
<relocation>
<pattern>gnu.trove</pattern>
<shadedPattern>org.elasticsearch.common.trove</shadedPattern>
</relocation>
<relocation>
<pattern>jsr166y</pattern>
<shadedPattern>org.elasticsearch.common.util.concurrent.jsr166y</shadedPattern>
</relocation>
<relocation>
<pattern>jsr166e</pattern>
<shadedPattern>org.elasticsearch.common.util.concurrent.jsr166e</shadedPattern>
</relocation>
<relocation>
<pattern>org.mvel2</pattern>
<shadedPattern>org.elasticsearch.common.mvel2</shadedPattern>
</relocation>
<relocation>
<pattern>com.fasterxml.jackson</pattern>
<shadedPattern>org.elasticsearch.common.jackson</shadedPattern>
</relocation>
<relocation>
<pattern>org.joda</pattern>
<shadedPattern>org.elasticsearch.common.joda</shadedPattern>
</relocation>
<relocation>
<pattern>org.jboss.netty</pattern>
<shadedPattern>org.elasticsearch.common.netty</shadedPattern>
</relocation>
<relocation>
<pattern>com.ning.compress</pattern>
<shadedPattern>org.elasticsearch.common.compress</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/license/**</exclude>
<exclude>META-INF/*</exclude>
<exclude>META-INF/maven/**</exclude>
<exclude>LICENSE</exclude>
<exclude>NOTICE</exclude>
<exclude>/*.txt</exclude>
<exclude>build.properties</exclude>
</excludes>
</filter>
</filters>
</configuration>
</plugin>
</plugins>