2016-01-06 13 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。 –