2017-07-07 29 views
0

我正在使用Apache Karaf 4.1.1和Karaf Cellar。我寫了兩個捆綁包。第一個bundle提供了一個ITrackerManager類型的服務。第二個bundle有一個引用ITrackerManager的組件。我的最終目標是見證第二個包中的組件成功獲取對運行在不同節點上的第一個包中的ITrackerManager服務的引用。這是我對分佈式OSGi的探索的一部分。Apache Karaf Cellar的分佈式OSGi示例 - 由於無法找到分佈式服務,客戶端軟件包無法激活

當我安裝第二個軟件包時,實際發生的事情是它已安裝,但由於缺少服務引用而無法激活。我必須錯誤地進行我的測試。 關於如何去展示我的最終目標的任何想法;節點B上的組件成功使用節點A上的服務?


這是我迄今爲止如何運行我的測試。

節點A

[email protected]()> cluster:node-list 
    | Id    | Alias | Host Name | Port 
--+-------------------+-------+--------------+----- 
x | 159.4.251.58:5701 |  | 159.4.251.58 | 5701 
    | 159.4.251.58:5702 |  | 159.4.251.58 | 5702 

節點B

[email protected]()> cluster:node-list 
    | Id    | Alias | Host Name | Port 
--+-------------------+-------+--------------+----- 
    | 159.4.251.58:5701 |  | 159.4.251.58 | 5701 
x | 159.4.251.58:5702 |  | 159.4.251.58 | 5702 

到目前爲止好。我在我的電腦上運行兩個卡拉夫實例。兩個實例都可以看到對方。現在我想僅將第一個包安裝到節點A.爲了實現這個目標,我安裝包到集羣,然後專門從節點B.刪除

節點A

[email protected]()> cluster:bundle-install -s default mvn:myCompany/dosgi-example-part1/1.0-SNAPSHOT 

[email protected]()> cluster:bundle-list default 
Bundles in cluster group default 
ID | State | Lvl | Located  | Blocked | Version  | Name 
---+----------+-----+---------------+---------+----------------+-------------------------------------------------------------- 
0 | Active |  | cluster/local |   | 5.6.2   | System Bundle 
... 
67 | Active |  | cluster/local  |   | 1.0.0.SNAPSHOT | Distributed OSGi Example Part 1 

[email protected]()> cluster:service-list 
Service Class    | Provider Node 
--------------------------+------------------ 
myCompany.ITrackerManager | 159.4.251.58:5701 
          | 159.4.251.58:5702 

仍在尋找好。我的軟件包位於集羣中,在節點A(此時爲節點B)上爲本地節點,服務由集羣識別並在節點A和節點B上可用。現在從節點B移除該軟件包。

節點B

[email protected]()> cluster:bundle-list default 
Bundles in cluster group default 
ID | State | Lvl | Located  | Blocked | Version  | Name 
---+----------+-----+---------------+---------+----------------+------------------------------------------------------------- 
67 | Active |  | cluster/local |   | 1.0.0.SNAPSHOT | Distributed OSGi Example Part 1 

[email protected]()> bundle:list 
START LEVEL 100 , List Threshold: 50 
ID | State | Lvl | Version  | Name 
---+--------+-----+----------------+----------------------------------------------- 
75 | Active | 80 | 1.0.0.SNAPSHOT | Distributed OSGi Example Part 1 

[email protected]()> bundle:uninstall 75 

[email protected]()> cluster:bundle-list default 
Bundles in cluster group default 
ID | State | Lvl | Located  | Blocked | Version  | Name 
---+----------+-----+---------------+---------+----------------+-------------------------------------------------------------- 
67 | Active |  | cluster |   | 1.0.0.SNAPSHOT | Distributed OSGi Example Part 1 

[email protected]()> cluster:service-list 
Service Class    | Provider Node 
--------------------------+------------------ 
myCompany.ITrackerManager | 159.4.251.58:5701 

優秀。第一個包已從節點B中刪除,但仍顯示爲處於羣集中。兩個節點都同意我的服務現在僅在節點A上可用(因爲該節點已從節點B中刪除)。現在我只會在節點B上加載我的第二個包。這是我遇到問題的地方。我不使用cluster:bundle-install命令加載第二個bundle,因爲我不希望它以節點A結束。因此,我使用常規bundle:install命令來安裝第二個bundle。這會導致關於不滿意的參考的錯誤。

節點B

[email protected]()> bundle:install -s mvn:otherCompany/dosgi-example-part2/1.0-SNAPSHOT 
Bundle ID: 76 
Error executing command: Error installing bundles: 
     Unable to start bundle mvn:otherCompany/dosgi-example-part2/1.0-SNAPSHOT: org.osgi.framework.BundleException: Unable to resolve otherCompany.dosgi-example-part2 [76](R 76.0): missing requirement [otherCompany.dosgi-example-part2 [76](R 76.0)] osgi.wiring.package; (&(osgi.wiring.package=myCompany)(version>=1.0.0)(!(version>=2.0.0))) Unresolved requirements: [[otherCompany.dosgi-example-part2 [76](R 76.0)] osgi.wiring.package; (&(osgi.wiring.package=myCompany)(version>=1.0.0)(!(version>=2.0.0)))] 

[email protected]()> bundle:list 
START LEVEL 100 , List Threshold: 50 
ID | State  | Lvl | Version  | Name 
---+-----------+-----+----------------+----------------------------------------------------------------------------------------------------- 
76 | Installed | 80 | 1.0.0.SNAPSHOT | Distributed OSGi Example Part 2 

所以它就在那裏。我只在NodeB上安裝第二個軟件包,期望它能夠成功使用駐留在節點A上的所需服務。不幸的是,這並沒有發生。相反,我收到錯誤消息,指出有未解決的要求。它似乎表現得好像DOSGI不可用。如果我將兩個軟件包安裝在同一個節點上,則第二個軟件包將激活而不會出現任何錯誤。任何見解你可能會感激。

+0

我發現了一個karaf-cellar示例,它完全符合我的要求,在Node B上使用分佈式OSGi在客戶端調用的節點A上創建了一項服務。這些說明可以在下面的URL中找到。我運行了這個例子,它在我現有的Karaf實例中運行正常。我需要做更多的挖掘工作來弄清楚他們的例子與我的不同之處,以便確定我爲什麼不工作。 [工作Karaf Cellar DOSGi示例](https://github.com/apache/karaf-cellar/tree/master/samples/dosgi-greeter) – jonathan

回答

0

我的問題是雙重的。

  1. 通過DOSGI發送的東西需要可序列化。就我而言,我在一個遠程服務上調用了一個方法來引用一個參數。該參數是在通用API中定義的類類型。該類的類型不可序列化。一旦我使它可序列化,它就會出現不同的錯誤。這給我帶來了...

  2. 正常名稱空間規則適用。我將在下面詳細說明。

我的API定義了兩個接口。

  • ITracker
  • ITrackerManager

該API捆綁安裝到集羣,因此可用於所有節點上。我的服務包具有ITrackerManager的具體實現。當該軟件包在節點A上本地安裝時,cluster:service-list命令正確顯示節點A具有ITrackerManager類型的服務。

我的客戶端軟件包具有ITracker的具體實現,該實現引用了安裝在節點B上的ITrackerManager。ITracker實例在其激活方法中執行的第一件事是調用ITrackerManager.addTracker(this)。本來應該發生的事情是,Node B上的ITracker實例將自己提供給運行在Node A上的ITrackerManager。最初,這失敗了,因爲ITracker不可序列化。一旦解決了,我開始在節點A上看到classNotFound異常。

節點A試圖在本地反序列化ITracker實例。它試圖去定義一個沒有在本地定義的具體類(他們的追蹤器),它只在客戶端捆綁中的節點B上定義。這失敗了。

所以正常的命名空間規則適用。 儘管節點B上的客戶端軟件包具有對在節點B中運行的服務的引用,但節點A中的服務軟件包無法創建(即,反序列化)僅存在於節點B上的客戶端軟件包中的類的實例。

我切換了我的接口,以便ITrackerManager方法不需要ITracker爭論。相反,它需要一個字符串。在DOSGi上調用該方法可以正常工作。

雖然我明白爲什麼存在這個問題,但這破壞了我希望與DOSGi一起使用的核心功能。我希望客戶能夠註冊一個可以主動控制它們的中央控制器。這將不起作用,因爲即使客戶端實現中央控制器正在尋找的接口,中央控制器上的特定序列化也會失敗。客戶端具體類存在於中央控制器未知的名稱空間中,因此客戶端無法成功將自己傳遞給中央控制器。

這必須是一種方法來實現我在DSOGi中尋找的內容,而無需使每個多客戶端都成爲導出的DSOGi服務。有任何想法嗎?

相關問題