2009-10-14 23 views
9

Tôi đã tạo một gói OSGi với dịch vụ tiếp xúc (khai báo). Nếu tôi, khi kích hoạt được gọi, thông báo rằng một cái gì đó là không ổn thỏa như vậy mà tôi không thể cung cấp dịch vụ, tôi cần phải ngăn chặn nó được tiếp xúc. Tại thời điểm này chức năng kích hoạt trông giống như vậy:Cách thích hợp để vô hiệu hóa dịch vụ OSGi khi bắt đầu dịch vụ là gì?

public void activate(ComponentContext context, Map<String, Object> properties) { 
    pid = (String) properties.get(Constants.SERVICE_PID); 
    try { 
     ... 
    } 
    catch(Exception e) { 
     context.disableComponent(pid); 
    } 
} 

Một lựa chọn khác là chỉ cần quấn/tuyên truyền các ngoại lệ (hoặc ném một cái mới, tùy thuộc) như thế này:

public void activate(ComponentContext context, Map<String, Object> properties) { 
    try { 
     ... 
    } 
    catch(Exception e) { 
     throw new ComponentException("Some reason"); 
    } 
} 

tôi không thể tìm thấy hành vi chính xác được chỉ định trong phần về dịch vụ khai báo trong số OSGi Service Platform Service Compendium, nhưng tôi có thể thiếu một số thứ gì đó

Trả lời

8

Hmm, đối với tôi, có vẻ như một ngoại lệ phải được ném nếu xảy ra lỗi. Về cơ bản, những gì bạn đang làm sau đó là bắt chước hành vi của một BundleActivator trong phương thức bắt đầu. Gói đi vào trạng thái ACTIVE khi phương thức khởi động trả về mà không có một ngoại lệ (nếu không nó vẫn còn trong RESOLVED). Tôi tìm thấy một đoạn hơi phù hợp trong đặc điểm kỹ thuật DS (Tôi đã nêu bật phần thú vị):

Ví dụ thành phần phải hoàn tất kích hoạt trước khi nó có thể bị hủy kích hoạt. Khi cấu hình thành phần bị hủy kích hoạt hoặc không kích hoạt do ngoại lệ, SCR phải hủy liên kết tất cả các dịch vụ ràng buộc của thành phần và hủy tất cả các tham chiếu đến cá thể thành phần được liên kết với kích hoạt.

Mục 112.5.6 P.320 trong OSGi 4.2 cmpn spec

Tôi đồng ý rằng đây không phải là tinh thể rõ ràng, vì vậy nếu bạn muốn được ở bên an toàn (tốt hơn an toàn hơn xin lỗi), tôi muốn giới thiệu đến làm sự kết hợp (cho phép bởi spec).

public void activate(ComponentContext context, Map<String, Object> properties) { 
    try { 
     ... 
    } catch(Exception e) { 
     context.disableComponent((String) properties.get(Constants.SERVICE_PID)); 
     // not sure if a CE is best here... Maybe just rethrow the original one 
     throw new ComponentException("Some reason"); 
    } 
} 

Chúc mừng, Mirko

0

Một thành phần vô hiệu hóa chính nó là rất khó có khả năng là một thiết kế OSGi thích hợp. Điều gì sẽ cho phép các thành phần khi tình hình cải thiện? Trạng thái được bật/tắt được dự định là một mức logic khác so với kích hoạt/hủy kích hoạt.

Mã OSGI được thiết kế đúng cách nên xử lý đúng với mã ném ra một ComponentException (hoặc ngoại lệ khác) khi kích hoạt không thành công. Giả sử thành phần đăng ký một dịch vụ, tham chiếu dịch vụ sẽ có sẵn nhưng cố gắng để có được dịch vụ sẽ trả về null. DS sẽ xử lý chính xác các tham chiếu đến dịch vụ và bất kỳ mã nào trực tiếp cố gắng nhận dịch vụ từ tham chiếu dịch vụ phải xử lý đúng cách với khả năng dịch vụ đó không thực sự khả dụng.

Tuy nhiên, điều này có thể gây nhầm lẫn. Trong Felix DS, tôi đã triển khai một phần mở rộng, nhờ đó các thành phần có thể thay đổi các thuộc tính dịch vụ của riêng chúng, mặc dù điều này không được chấp nhận trong spec. Sử dụng phần mở rộng này, một thành phần có thể thêm thuộc tính dịch vụ như active = true khi kích hoạt hoặc sửa đổi thành công và loại bỏ nó khi sửa đổi không thành công hoặc ngừng hoạt động. Khách hàng của dịch vụ có thể lọc trên thuộc tính dịch vụ này, ví dụ: (active = true).

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