Có cách nào để loại trừ sự phụ thuộc của Maven trên toàn cầu không?


93

Tôi đang cố gắng tìm một cách “chung chung” để loại trừ một phần phụ thuộc bắc cầu khỏi được đưa vào mà không cần phải loại trừ nó khỏi tất cả các phần phụ thuộc vào nó. Ví dụ: nếu tôi muốn loại trừ slf4j, tôi làm như sau:

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

Điều này một phần là để làm sạch tệp pom, một phần để tránh các vấn đề trong tương lai với việc mọi người thêm các phụ thuộc vào phụ thuộc đó - và quên loại trừ nó.

Là có một cách?


2
Không giải quyết được vấn đề, nhưng maven-enforcer-plugin có một phụ thuộc cấm tính năng đó sẽ thất bại nếu xây dựng phụ thuộc không mong muốn lẻn vào Bạn vẫn phải tự loại trừ chúng, mặc dù: -. /
dnault

Một câu trả lời thay thế có sẵn ở đây: stackoverflow.com/a/39979760/363573
Stephan

Câu trả lời:


69

Không giúp đỡ à? http://jlorenzen.blogspot.com/2009/06/maven-global-excludes.html

"Giả sử tôi muốn loại trừ avalon-framework khỏi WAR của mình, tôi sẽ thêm phần sau vào POM dự án của mình với phạm vi được cung cấp. Điều này hoạt động trên tất cả các phụ thuộc bắc cầu và cho phép bạn chỉ định nó một lần.

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

Điều này thậm chí hoạt động khi chỉ định nó trong POM mẹ, điều này sẽ ngăn các dự án phải khai báo điều này trong tất cả các POM con. "


49
Nó vẫn chỉ là một vụ hack một phần - sự phụ thuộc sẽ không kết thúc bên trong tạo tác bản dựng nhưng nó vẫn có sẵn trong quá trình thử nghiệm.
Tuukka Mustonen

@TuukkaMustonen Còn runtimephạm vi thay vì providedphạm vi?
Stephan

Điều gì xảy ra nếu avalon-framework 4.1.3+ được bao gồm ở những nơi khác trong dự án? Xem một phản ứng ở đây: stackoverflow.com/a/39979760/363573
Stephan

Tôi không sử dụng Maven nữa vì vậy tôi không có tư cách để kiểm tra các câu trả lời khác, nhưng tôi khuyến khích mọi người xem xét chúng trong trường hợp có một câu trả lời không phải là hack một phần, theo @TuukkaMustonen
Joffer

18

Tôi đã tạo một bình rỗng và tạo phụ thuộc này:

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

Nó không phải là hoàn hảo bởi vì từ bây giờ bạn có một jar rỗng trong đường dẫn biên dịch / thử nghiệm của bạn. Nhưng đó chỉ là mỹ phẩm.


3
systemscope hiện không được dùng nữa: maven.apache.org/guides/introduction/…
Jason Young

Để tránh sử dụng systemphạm vi, hãy xem kho lưu trữ Maven ảo phiên bản99.grons.nl (Cảnh báo: chỉ HTTP) hoặc (chỉ dành cho commons-logging / log4j) xem "thay thế 3) phần mềm trống" tại đây: slf4j.org/faq.html#excludingJCL
seanf

16

Để mở rộng nhận xét của dnault :

Người ta có thể sử dụng quy tắc Cấm phụ thuộc của plugin Maven Enforcer để đảm bảo loại trừ các phụ thuộc. Người ta vẫn phải loại trừ chúng theo cách thủ công, nhưng quá trình xây dựng sẽ thất bại nếu bất kỳ ai thêm phần phụ thuộc vào nơi khác do nhầm lẫn.

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

Ngoài ra, có một yêu cầu tính năng mở: MNG-1977 Loại trừ phụ thuộc toàn cầu


2
Theo dõi câu trả lời của bạn và đọc cuộc thảo luận từ liên kết mà bạn cung cấp, tôi nhận ra rằng các bình không mong muốn đôi khi đi vào bình béo chỉ vì phiên bản maven được sử dụng trên cục bộ và trên máy chủ khác nhau nên logic đóng gói có thể thêm các phiên bản phụ thuộc khá khác nhau nếu chúng không được thực thi nghiêm ngặt. Để giải quyết vấn đề tương tự của mình, tôi đã sử dụng cấu hình spring-boot-maven-plugin / Loại trừ / loại trừ cho gói đóng gói lại <goal> </goal>.
aprodan

10

Xin nhắc lại, đây là câu trả lời từ tài liệu chính thức của Maven:

Tại sao các loại trừ được thực hiện trên cơ sở phụ thuộc, thay vì ở cấp POM

Điều này chủ yếu được thực hiện để đảm bảo đồ thị phụ thuộc có thể dự đoán được và để giữ cho các tác động kế thừa không loại trừ một phụ thuộc không nên bị loại trừ. Nếu bạn sử dụng phương pháp cuối cùng và phải đưa vào một trường hợp loại trừ, bạn nên hoàn toàn chắc chắn rằng phụ thuộc nào của bạn đang mang lại phụ thuộc bắc cầu không mong muốn đó.

Nếu ai đó muốn xây dựng một bản dựng mạnh mẽ hơn, có thể sử dụng một phạm vi phiên bản . Điều này sẽ đảm bảo rằng không có phiên bản phụ thuộc nào mới hơn có thể can thiệp vào dự án.

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

Bất kỳ phiên bản slf4j-api nào> = 1.4.2 sẽ được coi là được cung cấp (cung cấp) trong thời gian chạy, từ một classpath đã định cấu hình hoặc một vùng chứa.

Người giới thiệu

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.