Gibt es eine Möglichkeit, eine Maven-Abhängigkeit global auszuschließen?

90

Ich versuche einen „generischen“ Weg zu finden, um eine transitive Abhängigkeit von der Aufnahme auszuschließen, ohne sie von allen Abhängigkeiten ausschließen zu müssen, die davon abhängen. Wenn ich beispielsweise slf4j ausschließen möchte, gehe ich wie folgt vor:

  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-jmx</artifactId>
    <version>3.3.2.GA</version>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>3.4.0.GA</version>
    <type>jar</type>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>

Dies dient zum einen der Bereinigung der POM-Datei, zum anderen der Vermeidung zukünftiger Probleme mit Personen, die Abhängigkeiten hinzufügen, die von dieser ausgeschlossenen Abhängigkeit abhängen - und zum Vergessen, sie auszuschließen.

Gibt es einen Weg?

Sébastien Le Callonnec
quelle
2
Löst das Problem nicht, aber das Maven-Enforcer-Plugin verfügt über eine gesperrte Abhängigkeitsfunktion , die den Build fehlschlägt, wenn sich unerwünschte Abhängigkeiten einschleichen. Sie müssen sie jedoch manuell ausschließen: - /
dnault
Eine alternative Antwort finden Sie hier: stackoverflow.com/a/39979760/363573
Stephan

Antworten:

67

Hilft das? http://jlorenzen.blogspot.com/2009/06/maven-global-excludes.html

"Angenommen, ich möchte das Avalon-Framework von meinem WAR ausschließen, würde ich meinem Projekt-POM Folgendes mit einem bereitgestellten Umfang hinzufügen. Dies funktioniert über alle transitiven Abhängigkeiten hinweg und ermöglicht es Ihnen, es einmal anzugeben.

<dependencies>
  <dependency>
      <artifactId>avalon-framework</artifactId>
      <groupId>avalon-framework</groupId>
      <version>4.1.3</version>
      <scope>provided</scope>
  </dependency>
</dependencies>

Dies funktioniert sogar, wenn Sie es im übergeordneten POM angeben, wodurch verhindert wird, dass Projekte dies in allen untergeordneten POMs deklarieren müssen. "

Joffer
quelle
47
Es ist immer noch nur ein Teil des Hacks - die Abhängigkeit endet nicht im Build-Artefakt, ist aber während der Tests weiterhin verfügbar.
Tuukka Mustonen
@ TuukkaMustonen Was ist mit dem runtimeBereich anstelle des providedBereichs?
Stephan
Was passiert, wenn Avalon-Framework 4.1.3+ an anderer Stelle im Projekt enthalten ist? Eine Antwort finden Sie hier: stackoverflow.com/a/39979760/363573
Stephan
Ich benutze Maven nicht mehr, daher bin ich nicht in der Lage, die anderen Antworten zu testen, aber ich würde die Leute ermutigen, sie in Betracht zu ziehen, falls es einen gibt, der kein partieller Hack ist, gemäß @TuukkaMustonen
Joffer,
18

Ich habe ein leeres Glas erstellt und diese Abhängigkeit erstellt:

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <scope>system</scope>
    <systemPath>${basedir}/src/lib/empty.jar</systemPath>
    <version>0</version>
</dependency>

Es ist nicht perfekt, da Sie von nun an ein leeres Glas in Ihrem Kompilierungs- / Testpfad haben. Das ist aber nur kosmetisch.

Guus Bloemsma
quelle
3
systemUmfang ist jetzt veraltet: maven.apache.org/guides/introduction/…
Jason Young
Um die Verwendung des systemBereichs zu vermeiden , lesen Sie das virtuelle Maven-Repository version99.grons.nl (Warnung: nur HTTP) oder (nur für Commons-Logging / log4j) "Alternative 3) leere Artefakte" hier: slf4j.org/faq.html#excludingJCL
Seanf
14

Um den Kommentar von dnault zu erweitern :

Sie können die Regel "Verbotene Abhängigkeiten" des Maven Enforcer-Plugins verwenden, um sicherzustellen, dass Abhängigkeiten ausgeschlossen sind. Man muss sie immer noch manuell ausschließen, aber der Build schlägt fehl, wenn jemand die Abhängigkeit versehentlich an anderer Stelle hinzufügt.

<dependencies>
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-jmx</artifactId>
    <version>3.3.2.GA</version>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
</dependencies>

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>1.4.1</version>
    <executions>
      <execution>
        <goals>
          <goal>enforce</goal>
        </goals>
        <configuration>
          <rules>
            <bannedDependencies>
              <excludes>
                <exclude>org.slf4j:slf4j-api</exclude>
              </excludes>
            </bannedDependencies>
          </rules>
        </configuration>
      </execution>
    </executions>
  </plugin>
</plugins>

Außerdem gibt es eine offene Funktionsanforderung: MNG-1977 Globale Abhängigkeitsausschlüsse

Arend v. Reinersdorff
quelle
2
Nach Ihrer Antwort und dem Lesen der Diskussion über den von Ihnen bereitgestellten Link habe ich festgestellt, dass unerwünschte Gläser manchmal in fette Gläser gelangen, nur weil die auf lokaler und auf dem Server verwendeten Maven-Versionen unterschiedlich sind, sodass die Verpackungslogik ganz unterschiedliche Versionen von Abhängigkeiten hinzufügen kann, wenn sie nicht strikt durchgesetzt werden. Um mein ähnliches Problem zu lösen, habe ich die Spring-Boot-Maven-Plugin-Konfiguration / excludes / exclude für das <goal> -Repackage </ target> verwendet.
Aprodan
9

Zur Erinnerung, hier ist die Antwort aus der offiziellen Dokumentation von Maven:

Warum Ausschlüsse pro Abhängigkeit und nicht auf POM-Ebene vorgenommen werden

Dies geschieht hauptsächlich, um sicherzustellen, dass das Abhängigkeitsdiagramm vorhersehbar ist, und um zu verhindern, dass Vererbungseffekte eine Abhängigkeit ausschließen, die nicht ausgeschlossen werden sollte. Wenn Sie zur Methode des letzten Auswegs gelangen und einen Ausschluss vornehmen müssen, sollten Sie absolut sicher sein, welche Ihrer Abhängigkeiten diese unerwünschte transitive Abhängigkeit mit sich bringt.

Wenn man einen Build robuster machen möchte, kann ein Versionsbereich verwendet werden. Dies würde sicherstellen, dass keine neuere Version der Abhängigkeit das Projekt stören kann.

<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>[1.4.2,)</version>
   <scope>provided</scope>
</dependency>

Jede slf4j-api-Version> = 1.4.2 wird zur Laufzeit als angeboten (bereitgestellt) betrachtet, entweder aus einem konfigurierten Klassenpfad oder einem Container.

Verweise

Stephan
quelle