2009-09-08 50 views
14

Giả sử tôi có hai phụ thuộc Maven được định nghĩa trong một dự án như dưới đây.Phụ thuộc Maven trong sự phụ thuộc với phạm vi khác nhau

<dependency> 
     <groupId>com.thoughtworks.xstream</groupId> 
     <artifactId>xstream</artifactId> 
     <version>1.3.1</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>mycompany.library</groupId> 
     <artifactId>mylibrary</artifactId> 
     <version>1.0.1</version> 
     <scope>compile</scope> 
    </dependency> 

Sau đó, trong thư viện của tôi, tôi cũng có một phụ thuộc được định nghĩa như bên dưới.

<dependency> 
     <groupId>com.thoughtworks.xstream</groupId> 
     <artifactId>xstream</artifactId> 
     <version>1.3.1</version> 
     <scope>compile</scope> 
    </dependency> 

Khi tôi đóng gói dự án, tôi không thấy xstream được đóng gói trong đó. Tôi nghĩ rằng phạm vi phụ thuộc xstream của dự án, 'test' là ghi đè phạm vi phụ thuộc xstream của mylibrary, 'compile'.

Trong trường hợp này, cách tốt nhất để bao gồm xstream cho toàn bộ dự án để submodule có thể có quyền truy cập vào nó khi được đóng gói trong dự án là gì?

Tôi đã đọc giải thích về trang web của Apache Maven về phụ thuộc Transitive, nhưng tôi đang cố gắng hiểu ý nghĩa của nó, và cũng để tìm hiểu cách thực hành tốt nhất trong tình huống này.

Trả lời

11

Điều này thực sự lạ lùng với tôi và nếu đó là "tính năng", tôi nghĩ thực sự nguy hiểm. Dù sao, nó không phải là một lỗi Maven và nó trong tài liệu maven here.

Về thực hành tốt nhất về vấn đề này, tôi chưa từng nghe về bất kỳ cách nào, nhưng cách an toàn nhất để tiến hành phải loại bỏ hoàn toàn xstream khỏi pom của bạn, dựa vào sự phụ thuộc chuyển tiếp. Làm điều này sẽ dẫn đến lỗi xây dựng nếu phụ thuộc vào thư viện của tôi bị xóa. Điều này sẽ hoạt động như một thông báo cho bạn rằng bạn cần phải sửa chữa một cái gì đó. Bạn sẽ không âm thầm mất phụ thuộc cần thiết, và bạn sẽ không âm thầm có phụ thuộc bạn không còn cần.

Lưu ý phụ, phụ thuộc mvn: phân tích có thể được sử dụng để kiểm tra các phụ thuộc được bao gồm nhưng không được sử dụng.

0

Nếu bạn muốn nó được đóng gói, tại sao bạn khai báo phạm vi? Nếu nó được yêu cầu tại thời gian biên dịch và thực thi, bạn có nên để trống phạm vi không? Nếu bạn đã làm điều đó, thì bạn chỉ cần

<dependency> 
    <groupId>mycompany.modules</groupId> 
    <artifactId>submodule</artifactId> 
    <version>1.0.1</version> 
</dependency> 

trong pom của bạn. Trừ khi có một lý do để descope nó trong quá trình biên dịch nhưng không phải trong quá trình đóng gói?

+0

từ trang web Apache Maven: - biên dịch Đây là phạm vi mặc định, được sử dụng nếu không có quy định nào được chỉ định. Các phụ thuộc biên dịch có sẵn trong tất cả các classpath của một dự án. Hơn nữa, những phụ thuộc đó được truyền cho các dự án phụ thuộc. –

+0

Có lẽ câu hỏi ban đầu của tôi đã gây nhầm lẫn vì tôi đã sử dụng 'submodule'. Vui lòng xem câu hỏi đã chỉnh sửa của tôi ở trên. –

+0

Vâng, tôi đã tự hỏi hơn về phạm vi kiểm tra. – aperkins

4

Bằng cách tuyên bố sự phụ thuộc của riêng bạn trên xstream và đặt phạm vi để kiểm tra, bạn sẽ ghi đè phụ thuộc được khai báo bởi mylibrary.

Đây thực sự là một tính năng của Maven - nó cho phép bạn thực hiện những việc như phụ thuộc vào phiên bản sau của phụ thuộc chuyển tiếp trong dự án của riêng bạn và không đóng gói hai phiên bản khác nhau của cùng một tạo phẩm. Ví dụ: bạn có thể phụ thuộc vào phiên bản 1.2.15 của log4j, nhưng vì bạn cũng sử dụng libraryX phụ thuộc vào log4j-1.2.14 - bạn sẽ không muốn cả hai log4j-1.2.15log4j-1.2.14 được đóng gói cùng với dự án của mình.

Nếu bạn thực sự muốn xstream được đóng gói trong dự án của mình, bạn không nên khai báo phạm vi là test. Trên thực tế, nếu bạn xóa phụ thuộc được liệt kê của mình trên xstream, mọi thứ sẽ hoạt động như bạn muốn, vì mylibrary có phụ thuộc biên dịch trên đó ..

+1

Trong trường hợp đó, nếu một thời gian trong tương lai, tôi không cần phải sử dụng thư viện của tôi hoặc thư viện đó thay đổi sự phụ thuộc của nó trên xstream thành cái gì khác, dự án của tôi sẽ không vượt qua các bài kiểm tra. Sau đó, tôi sẽ cần phải xác định xstream cho phạm vi kiểm tra của dự án một lần nữa. Đây có phải là tính năng/giới hạn của Maven không? Tôi sẵn sàng chấp nhận những hạn chế của Maven, chỉ cần cố gắng xem thực hành tốt nhất là gì. –

+0

Tôi không chắc chắn điều này là chính xác. Có một cơ chế intutive hơn để loại trừ các phụ thuộc transitive không mong muốn, và đó là khối . – Buhb

+0

"nếu một thời gian trong tương lai, tôi không cần phải sử dụng thư viện của tôi hoặc thư viện đó thay đổi sự phụ thuộc của nó trên xstream thành cái gì khác, dự án của tôi sẽ không vượt qua các bài kiểm tra." sau đó tại thời điểm đó chỉ cần thêm phụ thuộc trở lại. Miễn là bạn tiếp tục dựa vào cùng một phiên bản của thư viện, không có thay đổi bất ngờ nào xảy ra. Các phiên bản mới của dự án của bạn có thể có những nhu cầu khác nhau - điều này hoàn toàn bình thường. –

5

Như câu trả lời của mattb nói, tuyên bố sự phụ thuộc là test phạm vi ghi đè khai báo phụ thuộc biên dịch vi phạm, và kết quả là phụ thuộc không được bao gồm trong chiến tranh đóng gói của bạn.

Nếu bạn chỉ cần phụ thuộc trong các bài kiểm tra của bạn vì 'mylibrary' cần nó để thực thi, bạn không nên khai báo phụ thuộc tại tất cả trong pom dự án của bạn. Hãy để quá trình phân giải phụ thuộc transitive xử lý nó.

Nếu dự án của bạn sử dụng bình xstream trực tiếp, bạn vẫn có thể dựa vào phụ thuộc chuyển tiếp, vì bạn sẽ cần một phiên bản tương thích cho dự án của bạn và 'mylibrary' để cả hai chạy ngược với jar xstream. Bạn nên có các bài kiểm tra đơn vị thực hiện chức năng và nếu mylibrary thay đổi phiên bản của xstream thành một phiên bản không tương thích, các bản dựng của bạn sẽ không thành công và bạn có thể giải quyết vấn đề tại thời điểm đó.

Nói chung tôi muốn nói bạn nên cố gắng tránh khai báo các phiên bản phụ thuộc trực tiếp trong các dự án đa mô-đun. Tôi khai báo các phiên bản trong một phần dependencyManagement của một POM cha mẹ để đứa trẻ chỉ cần khai báo groupId/artifactId. Ngoài ra, từ Maven 2.0.9 trở đi có phạm vi phụ thuộc bổ sung là import:

Phạm vi này chỉ được sử dụng trên phụ thuộc loại pom trong phần. Nó chỉ ra rằng POM được chỉ định nên được thay thế bằng các phụ thuộc trong phần của POM. Vì chúng được thay thế, các phụ thuộc với một phạm vi nhập khẩu không thực sự tham gia vào việc hạn chế sự chuyển đổi của sự phụ thuộc.

Vì vậy, sử dụng phạm vi nhập khẩu, bạn có thể xác định phiên bản phụ thuộc chung của bạn trong một POM duy nhất, nhập khẩu các phụ thuộc của POM đó vào phần dependencyManagement của bạn, và chỉ cần khai báo groupId/artifactId của sự phụ thuộc vào POMs khác của bạn.

Các vấn đề liên quan