Czy istnieje sposób globalnego wykluczenia zależności Mavena?

93

Próbuję znaleźć „ogólny” sposób wykluczenia zależności przechodnich z włączenia bez konieczności wykluczania jej ze wszystkich zależności od niej zależnych. Na przykład, jeśli chcę wykluczyć slf4j, wykonuję następujące czynności:

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

Ma to na celu po części wyczyszczenie pliku pom, po części w celu uniknięcia problemów w przyszłości z dodawaniem zależności zależnych od tej wykluczonej zależności - i zapominaniem o jej wykluczeniu.

Czy istnieje sposób?

Sébastien Le Callonnec
źródło
2
Nie rozwiązuje problemu, ale maven-enforcement-plugin ma funkcję zbanowanych zależności , która zawiedzie kompilację, jeśli
wkradną się
Alternatywna odpowiedź jest dostępna tutaj: stackoverflow.com/a/39979760/363573
Stephan,

Odpowiedzi:

69

czy to pomaga? http://jlorenzen.blogspot.com/2009/06/maven-global-excludes.html

"Zakładając, że chcę wykluczyć avalon-framework z mojego WAR, dodałbym do moich projektów POM z zakresem dostarczonym. Działa to we wszystkich zależnościach przechodnich i pozwala ci to określić raz.

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

Działa to nawet wtedy, gdy zostanie określone w nadrzędnym POM, co uniemożliwi projektom deklarowanie tego we wszystkich podrzędnych plikach POM ”.

Joffer
źródło
49
To wciąż tylko częściowy hack - zależność nie skończy się wewnątrz artefaktu kompilacji, ale nadal jest dostępna podczas testów.
Tuukka Mustonen,
@TuukkaMustonen A co z runtimezakresem zamiast providedzakresu?
Stephan,
Co się stanie, jeśli avalon-framework 4.1.3+ zostanie zawarty w innym miejscu projektu? Zobacz odpowiedź tutaj: stackoverflow.com/a/39979760/363573
Stephan
Nie używam już Mavena, więc nie jestem w stanie przetestować innych odpowiedzi, ale zachęcałbym ludzi do rozważenia ich na wypadek, gdyby istniał jeden, który nie jest częściowym hackiem, zgodnie z @TuukkaMustonen
Joffer
18

Utworzyłem pusty słoik i utworzyłem tę zależność:

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

Nie jest idealny, ponieważ od teraz masz pusty słoik na ścieżce kompilacji / testowania. Ale to tylko kosmetyka.

Guus Bloemsma
źródło
3
systemscope jest teraz przestarzały: maven.apache.org/guides/introduction/…
Jason Young
Aby uniknąć używania systemzakresu, zobacz wirtualne repozytorium Maven w wersji 99.grons.nl (Ostrzeżenie: tylko HTTP) lub (tylko w przypadku commons-logging / log4j) zobacz „alternatywne 3) puste artefakty” tutaj: slf4j.org/faq.html#excludesJCL
seanf
16

Aby rozwinąć komentarz dnault :

Można użyć reguły Banned Dependencies wtyczki Maven Enforcer, aby zapewnić wykluczenie zależności. Nadal trzeba je wykluczyć ręcznie, ale kompilacja zakończy się niepowodzeniem, jeśli ktoś przez pomyłkę doda zależność w innym miejscu.

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

Pojawiło się również otwarte żądanie funkcji: MNG-1977 Globalne wykluczenia zależności

Arend przeciwko Reinersdorff
źródło
2
Podążając za twoją odpowiedzią i czytając dyskusję z linku, który podałeś, zdałem sobie sprawę, że niechciane słoiki pojawiają się czasami w fat jar tylko dlatego, że wersje mavena używane na lokalnym i na serwerze są różne, więc logika pakowania może dodawać całkiem różne wersje zależności, jeśli nie są one ściśle egzekwowane. Aby rozwiązać podobny problem, użyłem konfiguracji wtyczki spring-boot-maven-plugin / excludes / exclude do <goal> przepakowania </goal>.
aprodan
10

Dla przypomnienia, oto odpowiedź z oficjalnej dokumentacji Mavena:

Dlaczego wykluczenia są dokonywane na podstawie zależności, a nie na poziomie POM

Robi się to głównie po to, aby upewnić się, że wykres zależności jest przewidywalny, i aby efekty dziedziczenia nie wykluczały zależności, której nie należy wykluczać. Jeśli dojdziesz do metody ostatniej szansy i musisz wprowadzić wykluczenie, powinieneś być absolutnie pewien, która z twoich zależności powoduje tę niechcianą zależność przechodnią.

Jeśli chcesz, aby kompilacja była bardziej wytrzymała, możesz użyć zakresu wersji . Zapewniłoby to, że żadna nowsza wersja zależności nie może kolidować z projektem.

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

Każda wersja slf4j-api> = 1.4.2 będzie traktowana jako oferowana (dostarczona) w czasie wykonywania, ze skonfigurowanej ścieżki klas lub kontenera.

Bibliografia

Stephan
źródło