Loại trừ tất cả các phụ thuộc bắc cầu của một phụ thuộc duy nhất


221

Trong Maven2, để loại trừ một phụ thuộc bắc cầu duy nhất, tôi phải làm một cái gì đó như thế này:

<dependency>
  <groupId>sample.group</groupId>
  <artifactId>sample-artifactB</artifactId>
  <version>1</version>
   <exclusions>
     <exclusion>
       <groupId>sample.group</groupId>
       <artifactId>sample-artifactAB</artifactId>
     </exclusion>
   </exclusions>
</dependency>

Vấn đề với cách tiếp cận này là tôi phải làm điều này cho mọi phụ thuộc bắc cầu được đóng góp bởi sample-artifactB.

Có cách nào để sử dụng một số loại ký tự đại diện để loại trừ tất cả các phụ thuộc bắc cầu cùng một lúc thay vì từng cái một không?


Đôi khi người ta cần sử dụng một phiên bản mới nhất của thư viện cho biết Spring 2.5.6 nhưng một số phụ thuộc khác bao gồm phiên bản cũ hơn, ví dụ struts2-spring-plugin (2.1.6) bao gồm Spring 2.5.3. Trong các kịch bản như vậy, có một yêu cầu để loại trừ hoặc ghi đè phiên bản.
Vinod Singh

1
Sử dụng Ivy. Đùa thôi.
Jake Toronto

Câu trả lời:


54

Đối với maven2 không có cách nào để làm những gì bạn mô tả. Đối với maven 3, có. Nếu bạn đang sử dụng maven 3, vui lòng xem câu trả lời khác cho câu hỏi này

Đối với maven 2 Tôi khuyên bạn nên tạo pom tùy chỉnh của riêng bạn cho phần phụ thuộc có <loại trừ> của bạn. Đối với các dự án cần sử dụng sự phụ thuộc đó, hãy đặt phụ thuộc vào pom tùy chỉnh của bạn thay vì tạo tác thông thường. Mặc dù điều đó không nhất thiết cho phép bạn loại trừ tất cả các phụ thuộc bắc cầu với một <loại trừ> duy nhất, nhưng nó chỉ cho phép bạn viết phụ thuộc một lần và tất cả các dự án của bạn không cần duy trì danh sách loại trừ dài và không cần thiết.


12
Tôi sẽ khuyên bạn không nên tạo ra pom của riêng bạn để khắc phục các loại trừ. Điều này làm cho bản dựng của bạn ít di động hơn và làm giảm sự hiểu biết.
Brian Fox

1
Trong trường hợp bạn không nhìn qua anwser được chấp nhận: jira.codehaus.org/browse/MNG-3832
Jakub Bochenski

@JakubBochenski câu trả lời tôi đã đưa ra là dành riêng cho maven 2, đây là câu hỏi mà câu hỏi này được gắn thẻ (tại thời điểm tôi viết nhận xét này). Liên kết của bạn chỉ có liên quan đến maven 3. Bất kể, tôi đã chỉnh sửa câu trả lời của mình để liên kết đến liên kết đến câu trả lời được đánh giá cao hơn.
cá voi 17/03/2015

306

Những gì đã làm việc cho tôi (có thể là một tính năng mới hơn của Maven) chỉ đơn thuần là thực hiện các ký tự đại diện trong thành phần loại trừ.

Tôi có một dự án đa mô-đun chứa mô-đun "ứng dụng" được tham chiếu trong hai mô-đun đóng gói WAR. Một trong những mô-đun được đóng gói WAR đó thực sự chỉ cần các lớp miền (và tôi chưa tách chúng ra khỏi mô-đun ứng dụng). Tôi thấy điều này để làm việc:

<dependency>
    <groupId>${project.groupId}</groupId>
    <artifactId>app</artifactId>
    <version>${project.version}</version>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Ký tự đại diện trên cả groupId và artifactId loại trừ tất cả các phụ thuộc mà thông thường sẽ truyền qua mô-đun bằng cách sử dụng phụ thuộc này.


9
* Ký tự đại diện cho nhóm và artifiact dường như đang hoạt động trong maven 3
nkr1pt

22
Tôi không biết làm thế nào bạn có thể tìm thấy nó hoạt động, vì Maven 3 cảnh báo rõ ràng về việc sử dụng dấu hoa thị: [WARNING] 'Depencies.dependency.exinating.exinating.groupId' cho <artifcat_id> với giá trị "*" không phù hợp với một mẫu id hợp lệ. [CẢNH BÁO] Rất khuyến khích khắc phục những sự cố này vì chúng đe dọa sự ổn định của bản dựng của bạn. [CẢNH BÁO] Vì lý do này, các phiên bản Maven trong tương lai có thể không còn hỗ trợ xây dựng các dự án không đúng định dạng như vậy Bạn có muốn cung cấp một số bằng chứng cho thấy nó được hỗ trợ và có thể được sử dụng không? Nếu không tôi sẽ coi nhận xét của bạn là cực kỳ sai lệch.

7
Hoạt động rất đẹp với Maven 3.0.4. Cảm ơn rất nhiều !
Evgeny Goldin

1
maven 3.0.4 -> nó không hoạt động tốt với tôi. kết quả jar rất khác nhau khi tôi sử dụng dấu hoa thị hoặc khi tôi loại trừ rõ ràng tất cả các phụ thuộc trực tiếp. nó có thể phải làm với thực tế là tôi đang sử dụng maven-assembly-plugin để tạo ra một lọ mỡ. trong trường hợp này, sự hờn dỗi được đề xuất không hoạt động!
gilad hoch

31
Phương pháp này là hợp lệ. Họ đã sửa lỗi cảnh báo mà những người khác đang báo cáo trong maven 3.2.1: problems.apache.org/jira/browse/MNG-3832
Ryan

32

Một điều tôi thấy hữu ích:

Nếu bạn đặt phụ thuộc với các loại trừ trong phần Quản lý phụ thuộc của POM gốc cho dự án của bạn hoặc trong POM quản lý phụ thuộc có thể nhập, thì bạn không cần lặp lại loại trừ (hoặc phiên bản).

Ví dụ: nếu POM cha của bạn có:

<dependencyManagement>
    <dependencies>
    ...         
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.2.1</version>
            <exclusions>
                <exclusion>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
     ....
  </dependencies>
</dependencyManagement>

Sau đó, các mô-đun trong dự án của bạn có thể chỉ cần khai báo phụ thuộc là:

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
        </dependency>

POM gốc sẽ chỉ định cả phiên bản và loại trừ. Tôi sử dụng kỹ thuật này cho gần như tất cả các dự án của chúng tôi và nó giúp loại bỏ rất nhiều sự lặp lại.


23

Ba năm trước tôi đã khuyến nghị sử dụng Phiên bản 99 Không tồn tại, nhưng bây giờ tôi đã tìm ra một cách tốt hơn, đặc biệt là vì Phiên bản 99 đang ngoại tuyến:

Trong POM gốc của dự án của bạn, hãy sử dụng maven-execcer-plugin để không xây dựng nếu sự phụ thuộc không mong muốn len vào bản dựng. Điều này có thể được thực hiện bằng cách sử dụng quy tắc phụ thuộc bị cấm của plugin :

<plugin>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>1.0.1</version>
    <executions>
        <execution>
            <id>only-junit-dep-is-used</id>
            <goals>
                <goal>enforce</goal>
            </goals>
            <configuration>
                <rules>
                    <bannedDependencies>
                        <excludes>
                            <exclude>junit:junit</exclude>
                        </excludes>
                    </bannedDependencies>
                </rules>
            </configuration>
        </execution>
    </executions>
</plugin>

Sau đó, khi thông báo cho bạn về một phụ thuộc không mong muốn, hãy loại trừ nó trong phần POM gốc <dependencyManagement>:

<dependency>
    <groupId>org.springframework.batch</groupId>
    <artifactId>spring-batch-test</artifactId>
    <version>2.1.8.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Bằng cách này, sự phụ thuộc không mong muốn sẽ không xuất hiện một cách tình cờ (không giống như <exclusion>dễ bị quên), nó sẽ không khả dụng ngay cả trong thời gian biên dịch (không giống như providedphạm vi), không có phụ thuộc không có thật (không giống như Phiên bản 99) và nó ' sẽ hoạt động mà không có kho lưu trữ tùy chỉnh (không giống như Phiên bản 99). Cách tiếp cận này thậm chí sẽ hoạt động dựa trên phiên bản, phân loại, phạm vi hoặc toàn bộ nhóm của tạo tác - xem tài liệu để biết chi tiết.


Lưu ý rằng ít nhất là theo Maven 3.1, phần <configuration>bị bỏ qua khi thực hiện mục tiêu từ dòng lệnh và phải được chuyển lên ngay bên dưới <plugin>.
David Harkness

Tôi chỉ tìm thấy những gì trông giống như một lỗi Maven khó chịu - phiên bản 3.5.2. Tôi có một dự án với các mô hình con trong đó tôi loại trừ một phụ thuộc tại <dependencyManagement>phần của cha mẹ . Chạy một mvn dependency:treedự án cụ thể đó sẽ không có sự phụ thuộc loại trừ nào cả. Nhưng tất cả các dự án nhập khẩu sự phụ thuộc đó sẽ không tôn vinh <exclusions>từ pom cha mẹ của dự án khác - dự án bị loại trừ sẽ leo vào !!! Tôi đã phải di chuyển <exclusions>đến từng mô-đun pom trực tiếp.
cbaldan

11

Tôi sử dụng cách giải quyết sau: thay vì cố gắng loại trừ cổ vật trong tất cả các phụ thuộc phù hợp, tôi rút ra sự phụ thuộc là "được cung cấp" ở cấp cao nhất. Ví dụ: để tránh vận chuyển xml-apis "bất kỳ phiên bản nào":

    <dependency>
        <groupId>xml-apis</groupId>
        <artifactId>xml-apis</artifactId>
        <version>[1.0,]</version>
        <scope>provided</scope>
    </dependency>


6

Có một cách giải quyết cho vấn đề này, nếu bạn đặt phạm vi của một phụ thuộc vào thời gian chạy , các phụ thuộc bắc cầu sẽ bị loại trừ. Mặc dù lưu ý điều này có nghĩa là bạn cần thêm vào xử lý bổ sung nếu bạn muốn đóng gói phụ thuộc thời gian chạy.

Để bao gồm sự phụ thuộc thời gian chạy trong bất kỳ bao bì nào, bạn có thể sử dụng mục tiêu sao chép của maven-phụ thuộc-plugin cho một tạo phẩm cụ thể .


1
Điều này giúp tôi giải quyết các vấn đề với trình biên dịch Android Dalvik không thể xử lý một số vùi chuyển tiếp hai cấp --- nhưng tôi phải sử dụng <scope>provided</scope>thay vì <scope>runtime</scope>.
Garret Wilson

6

nếu bạn cần loại trừ tất cả các phụ thuộc bắc cầu khỏi một tạo phẩm phụ thuộc mà bạn sẽ đưa vào một cụm, bạn có thể chỉ định điều này trong bộ mô tả cho plugin lắp ráp:

<assembly>
    <id>myApp</id>
    <formats>
        <format>zip</format>
    </formats>
    <dependencySets>
        <dependencySet>
            <useTransitiveDependencies>false</useTransitiveDependencies>
            <includes><include>*:struts2-spring-plugin:jar:2.1.6</include></includes>
        </dependencySet>
    </dependencySets>
</assembly>

3

Nếu bạn phát triển theo Eclipse, bạn có thể trong biểu đồ phụ thuộc POM Editor (bật tab nâng cao) tìm kiếm sự phụ thuộc mà bạn muốn loại trừ dự án của bạn và sau đó:

nhấp chuột phải vào nó -> "Loại trừ Maven Artifact ..." và Eclipse sẽ loại trừ bạn mà không cần phải tìm ra sự phụ thuộc nào mà lib được liên kết.


lưu ý rằng điều này chỉ hoạt động nếu bạn đang sử dụng plugin m2eclipse
Nicolas Mommaerts

2

Lý do của bạn để loại trừ tất cả các phụ thuộc bắc cầu là gì?

Nếu có một tạo phẩm cụ thể (chẳng hạn như ghi nhật ký chung) mà bạn cần loại trừ khỏi mọi phụ thuộc, cách tiếp cận Phiên bản 99 không tồn tại có thể giúp ích.


Cập nhật 2012: Đừng sử dụng phương pháp này. Sử dụng maven-thi hành-plugin và loại trừ . Phiên bản 99 tạo ra các phụ thuộc không có thật và kho lưu trữ Phiên bản 99 đang ngoại tuyến (có các máy nhân bản tương tự nhưng bạn không thể dựa vào chúng để trực tuyến mãi mãi; tốt nhất chỉ nên sử dụng Maven Central).


1

Trong một vấn đề mô phỏng tôi đã có sự phụ thuộc mong muốn được khai báo với phạm vi được cung cấp. Với cách tiếp cận này, các phụ thuộc bắc cầu được tìm nạp nhưng KHÔNG được bao gồm trong giai đoạn gói, đó là những gì bạn muốn. Tôi cũng thích giải pháp này về mặt bảo trì, vì không có pom, hoặc pom tùy chỉnh như trong giải pháp của cá voi, cần thiết để duy trì; bạn chỉ cần cung cấp sự phụ thuộc cụ thể trong container và được thực hiện


-2

Sử dụng maven mới nhất trong đường dẫn lớp của bạn .. Nó sẽ loại bỏ các tạo phẩm trùng lặp và giữ lại tạo tác maven mới nhất ..

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.