web-dev-qa-db-fra.com

Comment exclure une dépendance du projet du parent dans Maven?

Par exemple, j'ai 2 projets Maven. L'un est "projet-parent". L'autre est "projet-enfant". De toute évidence, "projet-enfant" est le sous-projet de "projet-parent". 

"project-parent" a une dépendance de log4j. Mais je veux l'exclure du "projet-enfant". Y a-t-il un moyen?

Vous pourriez dire que je devrais déplacer log4j de "project-parent" à "project-child". C'est totalement correct. Mais l'hypothèse est JE NE PEUX PAS modifier le POM de "project-parent".

Merci d'avance. 

28
Smartmarkey

Je pense que dans Maven2, il n'y a aucun moyen d'y parvenir, car c'est à cela que sert l'héritage POM . Cependant, il y a un truc auquel je peux penser:

Supposons que vous avez le droit de télécharger un artefact dans votre référentiel d'artefacts interne. Vous pouvez créer un fichier JAR vide et le déployer en tant que log4j: log4j, avec une version manifestement anormale (par exemple, log4j: log4j: 9999). Ajoutez une telle dépendance dans votre projet-enfant. Ensuite, la dépendance de parent dépendra d'un fichier JAR in-fact-empty.

10
Adrian Shum

Je ne connais pas de moyen d'exclure une dépendance, mais vous pouvez l'exclure de la distribution cible, mais c'est un peu un bidouillage. Vous devez modifier l'étendue de la dépendance en un élément que vous pouvez exclure de la distribution finale.

Alors, disons que mon parent avait une dépendance à Junit 4.8, dans mon pom vous dites:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.8</version>
    <scope>provided</scope>
</dependency>

Nous changeons donc la portée en fournie. Pour une explication de la procédure, voir ma réponse à NoClassDefFoundError: org/junit/AfterClass lors du traitement des annotations . Malheureusement, cela n’affecte pas la construction, mais lorsque vous copiez les dépendances pour la distribution finale, vous pouvez utiliser l’élément de configuration excludeScope pour ne pas copier la dépendance dans la distribution finale:

<plugin>
<artifactId>maven-dependency-plugin</artifactId>

<executions>
    <execution>
        <id>copy-libs</id>
        <phase>package</phase>
        <goals>
            <goal>copy-dependencies</goal>
        </goals>
        <configuration>
            <outputDirectory>${project.build.directory}/lib</outputDirectory>
            <excludeScope>provided</excludeScope>
        </configuration>
    </execution>
11
Matthew Farwell

J'ai rencontré la même question, tout comme vous ... Dans mon projet, appelons le pom parent est parent.pom. parent a défini log4j, slf4j comme ceci:

       <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j-api.version}</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${slf4j-api.version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j-log4j12.version}</version>
        </dependency>

projet enfant appelle une dépendance dans child.pom. Mais je ne veux pas la dépendance log4j-1.2.x et veux augmenter la version de slf4j.

Alors. J'ajoute la dépendance du parent

<dependency>
        <groupId>parent</groupId>
        <artifactId>myartifactId</artifactId>
        <version>${my parent version}</version>
</dependency>

et utilisez exclusions pour supprimer le log4j  

<dependency>
        <groupId>parent</groupId>
        <artifactId>myartifactId</artifactId>
        <version>${my parent version}</version>
        <exclusions>
            <exclusion>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
            </exclusion>
        </exclusions>
</dependency>

et ajouter explicitement les dépendances de slf4j et log4j2 dans pom enfant

 <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.6</version>
    </dependency>
    <dependency>
        <groupId>org.Apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.Apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.8.2</version>
    </dependency>

    <dependency>
        <groupId>org.Apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.8.2</version>
    </dependency>

    <dependency>
        <groupId>com.lmax</groupId>
        <artifactId>disruptor</artifactId>
        <version>3.3.4</version>
    </dependency>

puis utilisez mvn dependency: tree pour afficher la liste des dépendances, voyez toujours le log4j

[INFO] +- org.Apache.kafka:kafka_2.10:jar:0.8.2.0:compile
[INFO] |  +- com.yammer.metrics:metrics-core:jar:2.2.0:compile
[INFO] |  +- org.scala-lang:scala-library:jar:2.10.4:compile
[INFO] |  +- org.Apache.zookeeper:zookeeper:jar:3.4.6:compile
[INFO] |  |  +- org.slf4j:slf4j-log4j12:jar:1.7.5:compile
[INFO] |  |  +- log4j:log4j:jar:1.2.17:compile

ajoutons les exclusions sur cette dépendance ... supprimons ce gars.

    <dependency>
        <groupId>org.Apache.kafka</groupId>
        <artifactId>kafka-clients</artifactId>
        <version>0.10.1.1</version>
        <exclusions>
            <exclusion>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

puis relancez la commande pour vérifier la liste des dépendances. D'ACCORD! clair ~

J'espère que cela peut vous aider:>

1
aluenkinglee

Si je comprends la question, vous avez besoin de quelque chose comme ce qui suit. Il introduit une dépendance et exclut cette dépendance de l'ajout à sa liste de dépendances. Cela est souvent utilisé si vous souhaitez injecter une version plus récente d'un package à la place de celle référencée dans l'autre package.

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.15</version>
    <exclusions>
        <exclusion>
            <groupId>com.Sun.jmx</groupId>
            <artifactId>jmxri</artifactId>
        </exclusion>
        ...
    </exclusions>
    ...

Si vous parlez plutôt d'une relation <parent>, je ne suis pas sûr qu'il y ait un moyen de le faire. Pouvez-vous passer d'un <parent> à un <dependency>?

1
Gray

Une méthode simple pour y parvenir consiste à spécifier la dépendance dans l'enfant du projet, mais dans la portée "test" (ou quelle que soit la portée la plus légère disponible). Cela "masquera" la portée spécifiée dans projet-parent afin qu'elle ne soit disponible que pour le code de test et non disponible pour le code non-test à la fois lors de la compilation et de l'exécution.

Je suis tombé sur cette fonctionnalité de bug principalement par erreur. Dans mon cas, mon enfant de projet avait un frère de projet avec une dépendance de portée "compilée", alors que le projet de parent avait la même dépendance spécifiée (héritée d'un grand-parent) avec une portée "fournie". project-child était un exécutable, cependant, qui dépendait du projet-frère, ainsi une erreur NoClassDefFoundError a été générée à l'exécution à partir du projet-frère puisque le chemin de classe d'exécution du projet-enfant était utilisé, sans la dépendance 'fournie'. J'ai résolu ce problème en déplaçant la dépendance 'compile' de projet-frère vers projet-parent afin que la 'compilation' "masque" le "fourni".

0
fwc