尝试跟踪部署到apache karaf的捆绑中的服务。 ServiceTracker#addingService不会被调用

时间:2016-01-06 11:56:02

标签: java osgi karaf blueprint-osgi

我大致以这种方式向apache karaf添加OSGI服务MyService

  1. 创建并注释服务及其实现。
  2. public interface MyService {//...}
    
    @OsgiServiceProvider(classes=MyService .class)
    @Singleton
    public class MyServiceImpl implements MyService {//...}
    
    1. 使用maven build与blueprint-maven-pluginmaven-bundle-plugin来处理anotations。 OSGi-service的声明及其实现结果在bundle.jar!/OSGI-INF/blueprint/autowire.xml中:
    2. <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
      
      1. 将包含该捆绑功能的功能复制到karaf-home / deploy
      2. 现在我想出于兼容性原因将该服务绑定到JNDI名称。我尝试通过在init()中实施MyServiceImpl并使用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");
        

        为了调查我首先检查了捆绑包是否已启动并且该服务已添加到karaf控制台中:

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

        然后我使用debug参数重新启动了karaf并将断点设置为init()addedService()。观察显示:init()被调用,因此ServiceTracker应该正确地添加到包中。但addingService()并未被调用。

        我错过了什么?

1 个答案:

答案 0 :(得分:0)

在blueprint.xml中,您使用其界面&#34; com.foo.bar.MyService&#34;发布服务。因此,您需要在服务跟踪器查找中使用相同的名称。

顺便说一下。你为什么要使用ServiceTracker?如果您从impl的@PostConstruct发布服务,那么只需使用:

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