2010-05-04 33 views
7

Tôi đang sử dụng OSGi cho dự án mới nhất của mình tại nơi làm việc và nó khá đẹp về mặt mô đun và chức năng.Quy trình phát triển OSGi hợp lý là gì?

Nhưng tôi không hài lòng với quy trình phát triển. Cuối cùng, tôi dự định có 30-50 gói riêng biệt, được sắp xếp theo đồ thị phụ thuộc - được cho là, đây là những gì OSGi được thiết kế cho. Nhưng tôi không thể tìm ra một cách rõ ràng để quản lý các phụ thuộc tại thời điểm biên dịch.

Ví dụ: Bạn có các gói A và B. B phụ thuộc vào các gói được xác định trong A. Mỗi gói được phát triển dưới dạng một dự án Java riêng biệt.

Để biên dịch B, A phải nằm trên đường dẫn lớp javac.

Bạn:

  1. tham khảo vị trí hệ thống tập tin của dự án A trong xây dựng kịch bản của B?
  2. Xây dựng A và ném lọ vào thư mục lib của B?
  3. Dựa trên tính năng "dự án được tham chiếu" của Eclipse và luôn sử dụng đường dẫn lớp của Eclipse để xây dựng (ugh)
  4. Sử dụng thư mục "lib" chung cho tất cả các dự án và đổ các gói đó ra sau khi biên dịch?
  5. Thiết lập kho lưu trữ gói, phân tích tệp kê khai từ tập lệnh xây dựng và kéo xuống các gói yêu cầu từ kho lưu trữ?

No. 5 có vẻ sạch sẽ nhất, nhưng cũng giống như rất nhiều chi phí.

Trả lời

2

Về cơ bản, bạn có thể sử dụng:

  • phụ thuộc nguồn (với "dự án tham chiếu" Eclipse)
  • phụ thuộc nhị phân (sử dụng lọ bó Một)

Nhưng vì phụ thuộc nhị phân là sạch hơn nhiều, nó cũng là loại phụ thuộc tốt nhất được quản lý bởi một khung quản lý phát hành như maven.
Và bạn có thể tích hợp maven vào dự án Eclipse của mình thông qua m2eclipse.

Các Maven plugin để sử dụng sau đó sẽ là: maven-bundle-plugin, mà bạn có thể nhìn thấy trong hành động trong:

Hãy xem xét ví dụ thực tế hơn này bằng cách sử dụng triển khai Dịch vụ nhật ký của Felix.
Dự án Dịch vụ nhật ký bao gồm một gói duy nhất: org.apache.felix.log.impl.
Nó có sự phụ thuộc vào giao diện OSGi lõi cũng như sự phụ thuộc vào giao diện OSGi của bản tóm tắt cho các giao diện dịch vụ nhật ký cụ thể.Sau đây là các tập tin POM của nó:

<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>org.apache.felix</groupId> 
    <artifactId>org.apache.felix.log</artifactId> 
    <packaging>bundle</packaging> 
    <name>Apache Felix Log Service</name> 
    <version>0.8.0-SNAPSHOT</version> 
    <description> 
    This bundle provides an implementation of the OSGi R4 Log service. 
    </description> 
    <dependencies> 
    <dependency> 
     <groupId>${pom.groupId}</groupId> 
     <artifactId>org.osgi.core</artifactId> 
     <version>0.8.0-incubator</version> 
    </dependency> 
    <dependency> 
     <groupId>${pom.groupId}</groupId> 
     <artifactId>org.osgi.compendium</artifactId> 
     <version>0.9.0-incubator-SNAPSHOT</version> 
    </dependency> 
    </dependencies> 
    <build> 
    <plugins> 
     <plugin> 
     <groupId>org.apache.felix</groupId> 
     <artifactId>maven-bundle-plugin</artifactId> 
     <extensions>true</extensions> 
     <configuration> 
      <instructions> 
      <Export-Package>org.osgi.service.log</Export-Package> 
      <Private-Package>org.apache.felix.log.impl</Private-Package> 
      <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName> 
      <Bundle-Activator>${pom.artifactId}.impl.Activator</Bundle-Activator> 
      <Export-Service>org.osgi.service.log.LogService,org.osgi.service.log.LogReaderService</Export-Service> 
      </instructions> 
     </configuration> 
     </plugin> 
    </plugins> 
    </build> 
</project> 
+0

Phụ thuộc nhị phân là những điều nguy hiểm để đề xuất. Tôi đã giúp một khách hàng tuần trước gỡ lỗi một vấn đề bộ nạp lớp gây ra bởi có 2 bản sao của cùng một nhị phân jar trong 2 bó khác nhau. Khi họ đã cố gắng để vượt qua các trường hợp của các đối tượng từ các bình nhị phân từ một bó khác có ngoại lệ lớp đúc. Tốt hơn hết là sử dụng các câu lệnh gói nhập/xuất như chúng đã định. Trong trường hợp của khách hàng, giải pháp là tạo một gói từ bình nhị phân đã xuất các gói được yêu cầu. Sau đó, cả hai gói khách hàng đã nhập các gói mà họ cần từ gói mới. –

+0

Hm. Tôi đã hy vọng tránh Mavenizing toàn bộ dự án, nhưng tôi có thể không tránh được nó. – levand

+0

Bạn có theo dõi câu hỏi này không, bạn đã xử lý như thế nào? Tôi có một vấn đề rất tương tự mà tôi đã giải quyết thông qua việc phát minh lại bánh xe Maven. Phải mất rất nhiều công sức để tránh sử dụng Maven sau đó cuối cùng tôi đã kết thúc với một giải pháp mà là một tập hợp con của Maven mà cuối cùng tôi sẽ phải chuyển đổi sang Maven. Các phụ thuộc dự án càng phức tạp, càng có nhiều lợi ích mà Maven cung cấp đến từ một người thực sự không thích sự phức tạp của nó). – Chris

7

Công ty của tôi có 100 dự án bó và chúng tôi sử dụng Eclipse để quản lý sự phụ thuộc. Tuy nhiên, tôi không đề xuất phương pháp "Yêu cầu Plugins" để quản lý các phụ thuộc. Đặt cược tốt nhất của bạn là tạo Dự án Plugin. Chỉ xuất các gói từ mỗi dự án mà bạn muốn hiển thị. Sau đó, ở phía bên nhập khẩu thực hiện như sau:

mở trình biên tập Manifest

Chuyển đến tab phụ thuộc Trong phía dưới bên trái là một phần gọi là "Quản lý tự động của Dependencies"

Thêm bất kỳ plugin plugin hiện tại phụ thuộc vào đó

Khi bạn đã viết mã, bạn có thể nhấp vào liên kết "thêm phụ thuộc" trên tab đó để tự động tính toán các gói đã nhập.

Nếu bạn chạy từ Eclipse, thao tác này được thực hiện tự động cho bạn khi bạn thực thi.

Lợi ích của phương pháp này là các gói được xây dựng của bạn chỉ sử dụng cơ chế nhập/xuất gói phần mềm do OSGi xác định, trái ngược với một cái gì đó từ Eclipse.

Nếu bạn muốn tìm hiểu thêm, tôi khuyên bạn nên truy cập trang web này và đặt hàng sách. Nó là tuyệt vời.

http://equinoxosgi.org/

+0

Đó là giải pháp thực tế hơn nhiều (đề xuất dựa trên maven của tôi), được tích hợp với Eclipse PDE. +1 – VonC

2

Có một tùy chọn thứ 6, mà tôi đã sử dụng cho một số dự án, đó là sử dụng một dự án duy nhất Eclipse (không phải là một dự án plugin, nhưng chỉ là một dự án Java thông thường) và đặt tất cả mã nguồn trong đó. Một tệp xây dựng được liên kết với dự án sẽ đơn giản biên dịch tất cả các mã trong một lần truyền duy nhất và sau đó tạo các gói ra khỏi các lớp được biên dịch (sử dụng Bnd từ Ant hoặc từ BndTools sớm được phát hành). Điều này có nhược điểm là nó không tôn trọng khả năng hiển thị khi phát triển và biên dịch thời gian, nhưng ngược lại rằng nó là một mô hình phát triển thực sự đơn giản giúp bạn xây dựng và triển khai rất nhanh.

5

Vâng, hãy làm những gì bạn nên có một thời gian dài trước đây, triển khai riêng biệt và API ... ok, điều này không phải lúc nào cũng dễ dàng trên các hệ thống hiện có nhưng mô hình đó có tiếng nổ lớn. Khi API của bạn nằm trong một gói/jar riêng biệt (ổn định hơn nhiều), bạn có thể biên dịch các ứng dụng khách và triển khai với gói/jar đó.

Một trong những phẩm chất quan trọng của gói thành công là nó đưa ra ít giả định về thế giới bên ngoài nhất có thể. Điều này ngụ ý rằng bạn không phải biên dịch dựa vào các gói mà bạn chạy trong thời gian chạy, tôi có một sở thích để cố gắng không làm điều đó. Bạn chỉ nên biên dịch dựa vào nhóm phụ thuộc tối thiểu. Nếu các giả định được đưa ra thì chúng rõ ràng là các gói được nhập khẩu và việc sử dụng các dịch vụ. Các hệ thống OSGi được thiết kế tốt cố gắng sử dụng các dịch vụ cho tất cả các giao tiếp liên bó. Mô hình này không chỉ loại bỏ các vấn đề tải lớp mà còn làm cho thiết lập xây dựng của bạn được tách rời hơn.

Thật không may, hầu hết các mã được viết dưới dạng thư viện có giao diện khá rộng vì chúng mã hóa rất nhiều chức năng mà dịch vụ cung cấp ra khỏi hộp như Nhà máy và người nghe. Mã này có một mối quan hệ chặt chẽ giữa triển khai thực hiện và API, do đó bạn phải có cùng trên đường dẫn lớp trong khi biên dịch và trong OSGi. Một giải pháp cho vấn đề này là bao gồm loại mã này bên trong gói bằng cách sử dụng nó (nhưng chắc chắn rằng không có đối tượng nào của thư viện này bị rò rỉ cho các gói khác). Một chút tiêu thụ bộ nhớ thêm nhưng nó giúp bạn tiết kiệm từ một số nhức đầu.

Vì vậy, với OSGi, hãy thử tạo các hệ thống dựa trên các dịch vụ và biên dịch dựa vào API dịch vụ của họ, chứ không phải một gói triển khai.

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