2010-01-07 43 views
9

Tôi gần đây đã trở thành một fan hâm mộ lớn của Maven để kiểm soát chu kỳ xây dựng cho ứng dụng của tôi. Tuy nhiên tôi đã gặp phải một số cạnh thô với quản lý phụ thuộc của Maven. Tôi tự hỏi nếu đây là những hạn chế của các công cụ và mô hình, tệ nạn cần thiết của quản lý dependancy, hoặc nếu tôi "m chỉ sử dụng công cụ này không đúng cách.quản lý phụ thuộc với maven

  1. Đầu tiên là vấn đề phụ thuộc bắc cầu. Theo tôi được biết , nếu bạn cung cấp một sự phụ thuộc, Maven sẽ lần lượt tìm thấy bất kỳ phụ thuộc của phụ thuộc mà đó là tuyệt vời, nhưng đối với nhiều người phụ thuộc của tôi, điều này đã không làm việc Ví dụ, bao gồm Hibernate trong dự án của tôi:..

    <dependency> 
        <groupId>org.hibernate</groupId> 
        <artifactId>hibernate-core</artifactId> 
        <version>3.3.2.GA</version> 
    </dependency> 
    

    Kết quả trong một thiếu phụ thuộc của slf4j.Tôi cần phải tự thêm phụ thuộc này mà tôi giả định sẽ là công việc của Maven.Cùng cùng cho mùa xuân.Nếu tôi thêm Spring-MVC như là một phụ thuộc, không phải tất cả các phụ thuộc servlet cơ bản sẽ được thêm vào cho tôi (vì Spring-MVC sẽ cần thứ này)? Tôi đang đề cập đến các thư viện servlet, jsp, jstl.

  2. Thứ hai là quản lý kho. Maven đi kèm với một kho lưu trữ chính mặc định, nhưng tôi thấy rằng trong nhiều trường hợp, kho lưu trữ này không được cập nhật. Ví dụ, nếu bạn muốn spring3, bạn phải tự thêm kho lưu trữ springource, và nếu bạn muốn hibernate 3.5+ bạn phải thêm kho jboss. Dường như đánh bại điểm quản lý phụ thuộc tự động khi bạn phải tự mình tìm kiếm kho lưu trữ chính xác. Săn bắn này sớm trở nên phức tạp. Ví dụ để thêm Spring3, bạn có thể muốn repo phát hành vào mùa xuân, repo xuân bên ngoài và repo cột mốc mùa xuân.

  3. Liên quan chặt chẽ đến số 2 là đảm bảo bạn có phiên bản chính xác của tạo phẩm. Tôi đã bị đốt cháy nhiều lần bằng cách bao gồm các phiên bản sai của các tạo phẩm phụ thuộc cho một tạo phẩm nhất định. Ví dụ, phiên bản sai của aplet servlet/jsp/jstl cho spring3, hoặc phiên bản sai của apis persistence/annotation cho hibernate. Các kho lưu trữ được lấp đầy với nhiều phiên bản, một số có tên khó hiểu như productx-3.ga, productx-3-rc1, productx-3-SNAPSHOT, productx-3-cr, sản phẩm-3-beta, v.v. Một số trong số này là hiển nhiên (rc = phát hành ứng cử viên), nhưng nó có thể gây nhầm lẫn cố gắng để xác định thứ tự của các phiên bản này.

  4. Cuối cùng, vấn đề thuộc loại phụ thuộc. Tôi có lẽ chỉ không hiểu điều này đủ tốt, nhưng nhiều hiện vật repo là loại "pom" không "jar". Một vài lần tôi đã thêm một jar phụ thuộc vào dự án của tôi chỉ để tìm hiểu tại thời điểm xây dựng mà repo jar không thực sự tồn tại (ví dụ là org.hibernate ejb3-persistence trong repo jboss).

Với một số thử nghiệm, tôi thường có thể xây dựng để làm việc, nhưng quản lý phụ thuộc nói chung phức tạp này? Tôi vẫn thích cách tiếp cận này để thêm thủ công các tệp jar vào dự án của tôi, nhưng tôi sẽ quan tâm để tìm hiểu cách cải thiện các kỹ năng quản lý phụ thuộc của maven của tôi.

Trả lời

14

Không thể trả lời tất cả các bộ phận của câu hỏi, nhưng về một số trong số họ:

  • Một số dependecies bắc cầu được đánh dấu optional, vì vậy những người không cần các tính năng này sẽ không tải về chúng, nhưng mọi người, những người cần, phải đặt chúng rõ ràng trong poms của họ.

  • Kho lưu trữ trung tâm Maven chỉ chứa các bản phát hành. Do đó, nó không chứa Hibernate 3.5 (là phiên bản beta) cũng như chưa có Spring 3 cho đến khi nó được phát hành (bằng cách này, bạn không cần phải chỉ định kho lưu trữ Spring đặc biệt cho Spring 3 nữa - bản phát hành đã có trong Maven Central)

  • slf4j là một loại phụ thuộc rất đặc biệt - hành vi thời gian chạy của nó phụ thuộc vào việc triển khai slf4j mà bạn sử dụng. Vì vậy, để kiểm soát hành vi của nó, bạn phải chỉ định thực hiện một cách rõ ràng slf4j

  • Về kỹ năng quản lý: để có được thông tin hữu ích cho việc duy trì của bạn pom.xml bạn có thể sử dụng mvn dependency:tree (đặc biệt là với -Dverbose=true) và mvn dependency:analyze. Cũng có thể hữu ích khi kiểm tra tệp pom phụ thuộc của bạn để tìm phụ thuộc tùy chọn.

+0

cảm ơn tuyệt vời vì câu trả lời. Bạn có thể xây dựng trên ý tưởng về sự phụ thuộc tùy chọn không? Với tôi điều này không rõ ràng, hoặc là bạn có sự phụ thuộc hay bạn không. Nếu bạn không có nó, hơn Maven nên lấy nó, phải không? Hoặc là trường hợp, một số usecases cho một artifact không yêu cầu phụ thuộc đó, trong trường hợp đó sẽ có ít điểm int bao gồm nó (ví dụ nó sẽ là vô nghĩa để bao gồm hibernate-chú thích nếu bạn không sử dụng chú thích trong dự án của bạn). –

+0

Phụ thuộc tùy chọn là phụ thuộc được yêu cầu bởi cấu hình. Một thư viện mạng có thể khai báo một thư viện gộp nó phụ thuộc vào như một phụ thuộc tùy chọn; để chỉ những người muốn bật tính năng tổng hợp mới được yêu cầu tải xuống các phụ thuộc bổ sung. – notnoop

+0

Nếu bạn sử dụng nhật thực, plugin m2eclipse là _really_ tốt để xem cây phụ thuộc. –

3

Đầu tiên là vấn đề phụ thuộc transitive. Theo tôi hiểu, nếu bạn cung cấp một sự phụ thuộc, Maven sẽ lần lượt tìm ra bất kỳ phụ thuộc nào của sự phụ thuộc đó. Điều đó thật tuyệt vời, nhưng đối với nhiều người phụ thuộc của tôi, điều này đã không hiệu quả. (...)

Như đã chỉ ra, một số phụ thuộc có thể được đánh dấu là tùy chọn (và không được kéo transitively). Ý tưởng là một số phụ thuộc chỉ được sử dụng cho một số tính năng nhất định và sẽ không cần thiết nếu tính năng đó không được sử dụng. Nếu người dùng muốn sử dụng chức năng liên quan đến sự phụ thuộc tùy chọn, họ sẽ phải redeclare rằng phụ thuộc tùy chọn trong dự án của riêng họ. Vì vậy, điều này chỉ hoạt động như được thiết kế :)

Thứ hai là quản lý kho. Maven đi kèm với một kho lưu trữ chính mặc định, nhưng tôi thấy rằng trong nhiều trường hợp, kho lưu trữ này không được cập nhật. (...)

Thậm chí nếu ý tưởng đằng sau khái niệm về một trung tâm repo là cao quý, bạn có thể không khách quan mong đợi nó để chứa tất cả lọ trên thế giới. Một trong những lý do rõ ràng nhất là uploading artifacts to the Central Repository chỉ mất thời gian và tài nguyên không phải là vô hạn. Và bởi vì các công ty như RedHat JBoss hoặc SpringSource hoặc Sun hoặc thậm chí tôi cần sự linh hoạt, khả năng phản ứng (trong một từ, kiểm soát), không ngạc nhiên khi họ sử dụng kho lưu trữ của riêng họ. Và, thực sự, tôi rất vui vì họ phơi bày chúng. Nhưng thực tế, các dự án cần phải ghi lại nơi tìm thấy các đồ tạo tác của chúng nếu chúng không có sẵn ở số trung tâm. Chỉ trong trường hợp, bạn có thể tìm thấy điều này How to find dependencies on public Maven repositories? hữu ích. Trong môi trường doanh nghiệp, cách tốt nhất để xử lý việc này là thiết lập kho lưu trữ proxy tập trung (công ty). Xem this page để biết các giải pháp như vậy.

Liên quan chặt chẽ đến số 2 là đảm bảo bạn có phiên bản chính xác của tạo phẩm. (...)

Xin lỗi nhưng bạn cần một chút để biết mình đang làm gì. Một dự án không thể đoán cho bạn biết bạn đang sử dụng phiên bản JSTL nào. Sau đó, liên quan đến các phiên bản khác nhau của các tạo phẩm, quy ước đặt tên được sử dụng bởi các dự án không liên quan gì đến maven, đây là lựa chọn dự án/nhà cung cấp (ngoại trừ SNAPSHOT mà maven xử lý đặc biệt). FWIW, các sơ đồ được sử dụng phổ biến bao gồm: M1 = Milestone 1, RC1 = Release Candidate 1, GA = Tính khả dụng chung (bản phát hành cuối cùng), CR = Phát hành khách hàng (thường là bản sửa lỗi). Bạn cũng có thể thấy alpha, beta. Điều này thực sự phụ thuộc vào vòng đời dự án và quy ước (không có gì thực sự bất thường ở đây mặc dù).

Cuối cùng, vấn đề thuộc loại phụ thuộc.Tôi có lẽ chỉ không hiểu điều này đủ tốt, nhưng nhiều hiện vật repo là loại "pom" không "jar". (...)

Tôi nghĩ rằng bạn thực sự thiếu kinh nghiệm. Bạn dường như đang chiến đấu với các phụ thuộc trong khi mọi thứ diễn ra suôn sẻ cho tôi :) Có thể sử dụng một số repository search engine sẽ giúp ích.

1

Bạn cũng có thể loại trừ một số phụ thuộc bắc cầu, như ví dụ sau:

<dependency> 
     <groupId>log4j</groupId> 
     <artifactId>log4j</artifactId> 
     <version>1.2.15</version> 
     <exclusions> 
      <exclusion> 
       <groupId>javax.mail</groupId> 
       <artifactId>mail</artifactId> 
      </exclusion> 
      <exclusion> 
       <groupId>javax.jms</groupId> 
       <artifactId>jms</artifactId> 
      </exclusion> 
      <exclusion> 
       <groupId>com.sun.jdmk</groupId> 
       <artifactId>jmxtools</artifactId> 
      </exclusion> 
      <exclusion> 
       <groupId>com.sun.jmx</groupId> 
       <artifactId>jmxri</artifactId> 
      </exclusion> 
     </exclusions> 
    </dependency> 

Tôi không nhớ các chi tiết, nhưng dường như một số phụ thuộc khác đã được phát hiện khi chúng ta muốn sử dụng log4j, và chúng tôi đã không quan tâm (hoặc cần) trong họ trong trường hợp của chúng tôi, vì vậy tôi bò orker chỉ nói "không nhờ những" và nó hoạt động.

0
  1. Phụ thuộc transitive chỉ có ở đó nếu chúng được mã hóa rõ ràng trong POM của phụ thuộc trực tiếp của bạn. Đôi khi bạn thực sự không muốn chúng, hoặc bởi vì có những triển khai thay thế hoặc bạn chỉ sử dụng một phần của thư viện và bạn không muốn kéo phụ thuộc vào những thứ bạn thực sự không sử dụng.

  2. Bạn đang sử dụng trình quản lý kho lưu trữ chẳng hạn như Nexus, phải không? Tôi khuyên bạn nên thiết lập ngay cả khi bạn mã một mình.

  3. Tôi thấy rằng Maven thực sự giúp giải quyết vấn đề này. Tôi ghét phải thực hiện thử nghiệm và lỗi này từ các trang FTP và các trang tải xuống.

  4. Vâng, tôi ghét điều đó quá :-)

Đọc book! Tôi thực sự đã học hầu hết những gì tôi biết từ this other book, nhưng do nó đến từ cùng một người, tôi hy vọng họ có thể thay thế được.

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