2011-04-19 50 views
2

這是另外一個問題重複,但複製從其他的一個:OSGi:在聲明式服務組件激活方法中註冊服務是否有效?

我碰到與Felix SCR一個問題,我得到的消息:)

ServiceFactory.getService(導致週期

這種情況出現的原因是因爲在激活方法中,將其稱爲ServiceAImpl(它提供ServiceA),服務註冊另一個服務,將其稱爲ServiceB。

我有另一個服務組件,稱之爲ServiceCImpl,這取決於ServiceA和ServiceB。通過ServiceAImpl註冊ServiceB,ServiceCImpl已經滿足並且在相同的調用中激活ServiceAmpl,調用ServiceCImpl綁定方法。當調用ServiceA的綁定方法時,會檢測到週期,並且組件無法初始化。

也許有一種方法可以讓SCR等待綁定ServiceCImpl,或者我需要以不同的方式註冊ServiceB?

我想什麼是沒有道理的是爲什麼菲利克斯SCR將激活ServiceAlmpl激活方法內的ServiceCImpl。我不認爲ServiceCmpl會在激活方法退出後纔會被認爲是滿足的。也許這是使用聲明式服務的問題,同時仍然直接向框架註冊服務?

還沒有嘗試其他SCR的實現,如Equinox的版本,但我可能會嘗試,看看是否有區別,但也許有人知道這是一個OSGi的東西或菲利克斯的東西?

附加信息:至於爲什麼ServiceB不是服務組件... ServiceA實際上對另一個服務具有0..n的服務引用,因此將其稱爲ServiceD。每當一個ServiceD接口由一個組件提供時,ServiceB就會使用同一個服務對象進行註冊。通常,同一個ServiceD提供者可以提供ServiceB,但是想法是讓開發人員的整體接口更加簡單化,因此他們不必提供多個服務接口(同樣,ServiceB具有一些必須自動設置的屬性手動完成,可能會錯誤地完成)。

+1

你不能註冊ServiceB作爲一個組件嗎? – 2011-04-19 15:41:04

+0

合併您的帳戶。 – Will 2011-04-26 12:17:11

回答

1

看起來發生這種情況的原因是ServiceAImpl是一個延遲的組件,它已經被加載,所以ServiceA實際上已經在組件被激活之前被調用。但是,當需要ServiceA的另一個組件出現時,這會導致ServiceAImpl被激活。 ServiceAImpl的部分激活過程是註冊ServiceB,它立即使ServiceCImpl被激活。 FELIX-2368進行了一項更改,通過使大多數SCR操作同步來立即激活組件。

解決方法是使ServiceAImpl成爲不需要的直接組件,因爲如果什麼都不需要該服務,它應該不會被激活。在這種情況下,激活方法在組件加載完成時完成,並在需要時綁定到另一個組件,這沒有問題。

0

我試着用一小套測試包和ProSyst OSGi FW重新創建這個場景。 但是,如果我向DS註冊服務,則無法在activate()方法中註冊其他服務。如果我只是使用DS來獲得服務,我可以照常註冊服務。因此,有可能是真的DS/SCR一個問題...

例子:

public class ServiceAImpl implements ServiceA, ServiceB, ManagedService { 

public void activate(ComponentContext _context) { 
    _context.getBundleContext().registerService(
      ManagedService.class.getName(), 
      this, 
      null); 
    _context.getBundleContext().registerService(
      ServiceB.class.getName(), 
      this, 
      null); 
} 


@Override 
public void doA() { 
    System.out.println("Doing A Stuff"); 

} 


@Override 
public void doB() { 
    System.out.println("Doing B Stuff"); 
} 


@Override 
public void updated(Dictionary arg0) throws ConfigurationException { 

} 

} 這個類將與此BND註冊2個服務(ServiceB,ManagedService)。文件:

Private-Package: org.test.impl 
Service-Component: org.test.impl.ServiceAImpl 
Bundle-Category: test 

但只有1個服務(ServiceA)此示例:#

Private-Package: org.test.impl 
Service-Component: org.test.impl.ServiceAImpl;provide:=org.test.ServiceA 
Bundle-Category: test 

那麼可能是你應該/必須嘗試通過DS/SCR或「經典的方式註冊無論是服務「通過捆綁上下文。

相關問題