2012-04-17 104 views
6

我想將我的EE應用程序遷移到OSGi。我的應用程序由業務庫,數據庫JPA /實體和REST/WS接口組成。它也有一個網絡客戶端。OSGi JAX-RS和bnd聲明式服務

我首先進行原型構造,並使所有接口和包以OSGi乾淨的方式彼此交談。我希望儘可能使用清晰的規範,而無需任何特定的供應商或框架。

我使用bnd maven插件來生成清單和聲明性服務。我想用注射像這樣,使我從剩下的資源OSGi服務的呼叫(在另一個bundle):

@Path("some-resources") 
@Component 
public class SomeResources{ 

    private SomeService service = null; 

    @Reference 
    public void setController(SomeService service) { // <- this is never called 
    this.service = service; 
    } 

    @GET 
    @Produces(javax.ws.rs.core.MediaType.APPLICATION_XML) 
    public Object getSomeService() {     // <- called 
    try { 
     service.process("Hello World");    // <- Error null object 
    } 
    ... 

} 

我可以標註與BND @Component和資源可以在@Resource注入? 一切工作正常,但服務始終爲空。

應該如何聲明我的捆綁包使BND成爲一個web/wab包?

我用maven捆綁:

<packaging>bundle</packaging> 

... 

     <plugin>      
       <groupId>org.apache.felix</groupId> 
       <artifactId>maven-bundle-plugin</artifactId> 
       <version>2.3.7</version> 
       <extensions>true</extensions> 
       <dependencies> 
        <dependency> 
         <groupId>biz.aQute</groupId> 
         <artifactId>bndlib</artifactId> 
         <version>1.50.0</version> 
        </dependency> 
       </dependencies> 
       <configuration> 
        <supportedProjectTypes> 
         <supportedProjectType>ejb</supportedProjectType> 
         <supportedProjectType>war</supportedProjectType> 
         <supportedProjectType>wab</supportedProjectType> 
         <supportedProjectType>bundle</supportedProjectType> 
         <supportedProjectType>jar</supportedProjectType> 
        </supportedProjectTypes> 
        <instructions> 
         <_include>-osgi.bundle</_include> 
        </instructions> 
       </configuration> 
       <executions> 
        <execution> 
         <id>bundle-manifest</id> 
         <phase>process-classes</phase> 
         <goals> 
          <goal>manifest</goal> 
         </goals> 
        </execution> 
        <execution> 
         <id>bundle-install</id> 
         <phase>install</phase> 
         <goals> 
          <goal>install</goal> 
         </goals> 
        </execution> 
       </executions> 
      </plugin>      

... 

與BND說明

Web-ContextPath: my-root-http/rest/ 
Service-Component: * 
+0

我最近遇到了類似的問題(服務沒有被綁定),並追蹤到[split package](http://wiki.osgi.org/wiki/ Split_Packages)問題。您是否嘗試將您的服務接口放入單獨的包中? – 2012-04-18 07:22:51

+0

謝謝@BjörnPollex的建議。我有3個軟件包,一個只有接口,一個帶有服務實現和REST bundel。我實際上將它移回到REST bundel,看看這樣做是否有效,但沒有運氣。如果我正在做的事情是正確的,那麼可能問題在於SCR找不到我的DS xml。 – Gadi 2012-04-18 07:29:20

+0

感謝編輯@donalfellows – Gadi 2012-04-18 07:30:51

回答

5

的OSGi有一個叫做遠程服務規範的一部分。在很短的時間內,它的工作方式就是您可以使用特殊服務屬性註冊服務,並且基於屬性技術應該提取服務並從中創建端點。它不僅關於REST,而且關於處理遠程呼叫的任何技術。您可以在「遠程服務」一章下的OSGi Core規範中找到相關信息。

那麼這是一個規範,但誰來實現它?目前我嘗試過兩個更大的項目。 CXF DOSGi和Eclipse ECF。他們提供了多種支持遠程服務規範的技術。 CXF特別支持基於服務器和客戶端實現的Jax-RS。

因爲我不想在OSGi內部使用彈簧特定的解決方案,所以我沒有在最後使用CXF,但創建了我自己的解決方案。它基於Jersey和遠程服務規範。當使用service.exported.interfaces = *和service.exported.configs = org.everit.osgi.remote.jersey指定OSGi服務時,它將使用HttpService在/ rest/path下創建一個休息端點。你的捆綁包不必是一個簡單的捆綁包。

我必須提到,如果您通過任何遠程服務實現公開您的服務,您應該將Jax-RS註釋放入由原始類實現的接口中,並基於該接口公開您的服務。

取代OSGi中的@Resource和@Component註解,我建議您應該使用與Spring非常相似的Blueprint(OSGi規範的一部分)。目前Apache Aries和Gemini Blueprint實現它。藉助藍圖,您可以輕鬆創建豆類並將它們連接到彼此。如果以這種方式註冊遠程服務,您可以藉助藍圖設置任何屬性(就像spring applicationcontext.xml中的bean屬性一樣)。

你可以在https://source.everit.biz/svn/everit-osgi/trunk/samples/jaxrs/(user/passwd:guest/guest)找到一個示例應用程序。有一本指南解釋瞭如何在http://cookbook.everit.org

上啓動和開發此樣本。我希望示例應用程序可以幫助您開始使用遠程服務規範章節。

要了解如何使用JPA和Injection(Blueprint),您應該檢查OSGi綱要規範的可能性並找到您喜歡的實現。我還做了一個基於藍圖和hibernate-jpa的示例項目,您可以找到我已經提供的示例url的兄弟。

更新

還有我在https://github.com/everit-org/osgi-remote-jersey做了JAXRS擴展實現。請參閱自述文件以獲取文檔。這與基於白板服務屬性的第一種方式不同。

2

我遇到過OSGi,Declarative Services和Jersey的類似問題。

資源可以使用@Component和@Reference註釋進行註釋。這將指示DS創建SomeResource類的實例,並在滿足所有依賴關係(引用)時向此實例注入有效引用。

您的引用爲空的原因是因爲JAX-RS實現將爲每個Web請求創建一個SomeResource類的新實例。 SomeResource類的這個實例與DS創建的實例不同。

我通過參考靜態變量與Java static關鍵字解決了這個問題:

private static SomeService service = null; 

這確保了依賴性引用綁定到一個類的對象,而不是一個實例,然後所有實例可以看到注入的價值。

該解決方案引入了一個新問題。此引用必須在解除綁定事件(服務不可用時)上清除,因爲當實例被銷燬時它不會被銷燬。

+0

存儲對osgi組件的靜態引用不是一個好主意。 – 2016-10-10 17:16:42

0

將@Path註釋類型註冊爲服務本身時,問題就會解決。有了DS,您可以注入其他服務。我近一年前就遇到過這個問題。這就是爲什麼我寫了一個小的OSGi JAX-RS連接器,它給你我所描述的。試試看如果你喜歡:https://github.com/hstaudacher/osgi-jax-rs-connector

相關問題