2016-01-06 36 views
0

我添加一个OSGi的服务MyService apache和karaf大致这样:试图跟踪部署到apache karaf的包中的服务。 ServiceTracker的#addingService不会被调用

  1. 创建和注释的服务及其imlementation。
public interface MyService {//...} 

@OsgiServiceProvider(classes=MyService .class) 
@Singleton 
public class MyServiceImpl implements MyService {//...} 
  • 使用行家建立与blueprint-maven-pluginmaven-bundle-plugin处理anotations。 OSGi的服务和bundle.jar其执行结果的声明/OSGI-INF/blueprint/autowire.xml:
  • <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" 
        xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"> 
    <bean id="myServiceImpl" class="com.foo.bar.MyServiceImpl" 
        ext:field-injection="true" init-method="init"> 
        <property name="contextFactory" ref="initialContextFactory-"/> 
    </bean> 
    <service ref="myServiceImpl" interface="com.foo.bar.MyService"/> 
    </blueprint> 
    

    ,XML是已知的包,因为它是在MANIFEST.MF:

    Bundle-Blueprint: OSGI-INF/blueprint/autowire.xml 
    
  • 复印包括束karaf家庭/部署
  • 现在我想以结合该服务为一个JNDI名称compatibil特征原因。我试图做到这一点通过实施MyServiceImplinit()和使用ServiceTracker

    @PostConstruct 
    public void init() { 
        BundleContext context = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); 
        ServiceTracker tracker = new ServiceTracker(context, this.getClass(), null) { 
         @Override 
         public Object addingService(ServiceReference reference) { 
          Object serviceObj = super.addingService(reference); 
          try { 
           Context c = new InitialContext(); 
           bind(c, "java:global/com.foo.bar.bundle/MyServiceImpl!com.foo.bar.MyService", serviceObj); 
          } 
          catch (NamingException e) { e.printStackTrace(); } 
          return serviceObj; 
         } 
        }; 
        tracker.open(); 
    } 
    
    private void bind(Context ctx, String name, Object value) { //... } 
    

    不幸的是,我得到一个javax.naming.NotContextException如果我做一个查询:

    new InitialContext().lookup("java:global/com.foo.bar.bundle/MyServiceImpl!com.foo.bar.MyService"); 
    

    探讨,我首先检查是否捆绑了开始和服务被添加到卡拉夫控制台:

    [email protected]()> bundle:list | grep bundle 
    155 | Active | 80 | 0.0.1.SNAPSHOT  | bundle 
    [email protected]()> bundle:services 155 
    
    bundle (155) provides: 
    ---------------------- 
    [com.foo.bar.MyService] 
    

    然后我重新启动卡拉夫与d ebug参数并将断点设置为init()addedService()。观察结果显示:init()被调用,所以ServiceTracker应正确添加到捆绑包中。但addingService()不会被调用。

    我错过了什么?

    回答

    0

    在blueprint.xml中,您使用其接口“com.foo.bar.MyService”发布服务。因此,您需要在服务跟踪器查找中使用相同的名称。

    Btw。你为什么要使用ServiceTracker?如果您从IMPL的@PostConstruct发布该服务,然后使用刚刚发布IMPL:

    Context c = new InitialContext(); 
    bind(c, "java:global/com.foo.bar.bundle/MyServiceImpl!com.foo.bar.MyService", this); 
    
    +0

    出于某种原因,我认为初始化bean和服务对象,我从包获得将2个不同的对象。删除'ServiceTracker'似乎解决了我的问题,不能100%肯定,因为现在我收到了另一个例外。为了理解,你能解释一下“服务跟踪器查找”的含义吗? –

    +0

    在这一行中,您将ServiceTracker配置为查找具有特定类名称“new ServiceTracker(context,this.getClass(),null)”的服务。你给的名字必须是服务发布的名称。 对象和服务确实不同。蓝图为该服务注册一个代理。如果您使用JPA或交易等拦截器,则需要此代理。 –

    +0

    是的,我确实使用交易。可能这就是为什么我收到错误消息“需要主动协调”。我还发现[日志](http://irclogs.dankulp.com/logs/irclogger_log/apache-karaf?date=2015-11-12,Thu&sel=472#l468),你在这里解释为什么抛出这个异常:)所以看来我真的需要一个ServiceTracker。 –