314 votes

À quoi sert l’ombre-maven-plugin, et pourquoi vous voulez déplacer des packages java ?

J'ai trouvé le maven-ombre-plugin utilisé dans quelqu'un pom.xml. Je n'ai jamais utilisé maven-ombre-plugin avant (et je suis un maven n00b) j'ai donc essayé de comprendre la raison de l'utilisation de ce et ce qu'il fait. J'ai regardé le maven docs, mais je ne peux pas comprendre cette déclaration: "Ce plugin offre la possibilité de package de l'artefact dans un uber-pot, y compris ses dépendances et à l'ombre, c'est à dire renommez - les emballages de certaines dépendances." La documentation sur la page ne semble pas très newbie-friendly.

Qu'est ce qu'un "uber pot?" Pourquoi quelqu'un voudrait-il le faire? Quel est le point de renommer les ensembles de dépendances? J'ai essayé d'aller à travers les exemples sur le maven-ombre-plugin apache page comme "la Sélection de contenu pour Uber Pot", mais je n'arrive toujours pas à comprendre ce qui est en train de s'accomplir avec la "trame de fond."

Les pointeurs vers des exemples d'illustration/cas d'utilisation (avec une explication de pourquoi l'ombrage a été nécessaire dans ce cas - quel problème est-il de problèmes) serait appréciée. Enfin, quand dois-je utiliser le maven-ombre-plugin?

377voto

Adrian Shum Points 10784

Uber POT, en un mot court, est un récipient contenant de tout.

Normalement dans Maven, on s'appuie sur la gestion de la dépendance. Un artefact juste contient les classes et/ou des ressources d'elle-même. Maven sera chargé de trouver tous les objets (Pots, etc) que le projet est tributaire, lors de la compilation et de l'exécution des etc.

Un uber-jar est quelque chose que prendre toutes les dépendances, et d'extraire le contenu de l'dépendances et le mettre dans un BOCAL, avec les classes et/ou des ressources du projet lui-même. Grâce à uber-pot, il est facile pour l'exécution, parce que vous aurez besoin d'un seul gros POT au lieu des tonnes de petits Pots pour exécuter votre application. Il a également facilité la distribution dans certains cas.

Juste une note. Évitez d'utiliser uber-jar comme Maven dépendance, comme il est de ruiner la dépendance de la fonction de résolution de Maven. Normalement, nous créer uber-jar seulement pour la finale de l'artefact pour le déploiement réel ou pour la distribution manuelle, mais pas pour la mise à Maven repo.


Mise à jour: je viens de découvrir que je n'ai pas répondu à une partie de la question : "Quel est le point de renommer les ensembles de dépendances?". Juste une brève mise à jour, et j'espère aider les autres.

La création d'uber-pot pour la facilité de déploiement est un cas d'utilisation de l'aide de l'ombre plugin. Il y a aussi un autre cas d'utilisation courants qui impliquent paquet renommer.

Je suis en train d'élaborer Foo bibliothèque, qui dépend d'une version spécifique (par exemple, 1.0) Bar bibliothèque. En supposant que je ne peut pas faire usage de l'autre version de l' Bar lib (parce que l'API de modifier, ou d'autres problèmes techniques, etc). Si je déclare simplement Bar:1.0 comme Foos'dépendance Maven, il est possible de tomber sur un problème: Un Qux projet dépend Foo, et également Bar:2.0 (et il ne peut pas utiliser Bar:1.0 car Qux besoin d'utiliser la nouvelle fonctionnalité Bar:2.0). Alors c'est un dilemme: dois-je utiliser Bar:1.0 ( Quxs'code ne fonctionnera pas) ou Bar:2.0 ( Foos'code ne fonctionnera pas).

Afin de résoudre ce problème, le développeur de Foo pouvez choisir d'utiliser l'ombre plugin pour renommer son utilisation de l' Bar, de sorte que toutes les classes en Bar:1.0 bocal est maintenant intégré dans Foo pot, et le paquet de l'embedded Bar classes est modifié à partir d' com.bar de com.foo.bar. Ce faisant, Qux pouvez en toute sécurité dépend Bar:2.0 parce que maintenant, en Foo n'est plus en fonction Bar, et c'est à l'aide de sa propre copie de "modifié" Bar situé dans un autre package.

72voto

Tom Points 435

Je me demandais moi-même récemment pourquoi elasticsearch nuances et les déplace un peu (mais pas tous) de ses dépendances. Voici une explication du projet responsable, @kimchy:

L'ombrage de la partie est intentionnel, le ombragée de bibliothèques que nous utilisons dans elasticsearch sont pour tous l'intention et le but de la partie d'elasticsearch, la version utilisée est étroitement liée à ce elasticsearch expose et comment il utilise la bibliothèque fondée sur les données internes de l'organisation de la bibliothèque (et que les changements entre les versions), netty et goyave sont de parfaits exemples.

Btw, je n'ai aucun problème avec le fait d'offrir plusieurs pots de elasticsearch, un avec lucene pas à l'ombre, et l'autre avec Lucene ombragée. Vous ne savez pas comment le faire avec maven. Je ne veux pas donner une version qui ne fait pas l'ombre netty/jackson par exemple, en raison de la profonde intimiate utilisation d'elasticsearch a avec eux (par exemple, à l'aide de la prochaine bufferring amélioration avec une précédente version de netty, sauf pour le courant on va effectivement utiliser plus de mémoire par rapport à l'utilisation de beaucoup moins).

-- https://github.com/elasticsearch/elasticsearch/issues/2091#issuecomment-7156766

Et un autre ici de drewr:

L'ombrage est important de garder nos dépendances (notamment netty, lucene, goyave) à proximité de notre code, de sorte que nous pouvons résoudre un problème, même si le fournisseur en amont à la traîne. Il est possible qu'il sera distribué modulaire versions du code, qui pourrait les aider avec votre problème particulier (#2091 par exemple), mais nous ne pouvons pas tout simplement supprimer la ombragée de dépendances à ce moment. Vous pouvez créer une version locale de ES pour vos besoins jusqu'à ce qu'il y a une meilleure solution.

-- https://github.com/elasticsearch/elasticsearch/pull/3244#issuecomment-20125452

Donc, c'est un cas d'utilisation. Comme pour l'exemple, ci-dessous comment maven-ombre-plugin est utilisé dans elasticsearch est pom.xml (v0.90.5). L' artifactSet::include des lignes de demander quelles sont les dépendances de tirer dans le uber JAR (en gros, ils sont décompressés et et ré-emballé côtés elasticsearch propres classes lorsque la cible elasticsearch pot est produit. (Au cas où vous ne le savez pas encore, un fichier JAR est juste un fichier ZIP qui contient le programme de cours, des ressources, etc., et certaines métadonnées. Vous pouvez extraire un pour voir comment il est mis en place.)

L' relocations::relocation des lignes sont similaires, sauf que, dans chaque cas, elles s'appliquent également spécifié substitution de la dépendance des classes - dans ce cas, conformément org.elasticsearch.common.

Enfin, l' filters section exclut les quelques trucs de la cible BOCAL ne pouvons pas être là - telles que le POT de métadonnées, ant, fichiers texte, etc. qui sont emballés avec des dépendances, mais qui n'appartiennent pas à un uber JAR.

<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>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X