2011-04-19 55 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或“经典的方式注册无论是服务“通过捆绑上下文。

相关问题