国家对卡拉夫的服务不满意(参考) - 错误在哪里? (OSGi,声明性服务,注释)

时间:2016-10-14 14:20:59

标签: java osgi karaf declarative-services

我有一个非常简单的服务提供商和消费者。出于某种原因,我无法解决我的消费者使用提供商服务的问题。 以下是提供者的包源代码:

package test;

import org.osgi.framework.BundleContext;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;

@Component (name = "MyProvider", immediate = true)
public class TestClass implements SimpleMathI {

    public TestClass() {
        System.out.println("contructing TestClass");
    }

    @Activate
    protected void activate(ComponentContext c, BundleContext b) {
        System.out.println("activate testClass ");
    }

    @Deactivate
    protected void deactivate() {
        System.out.println("de-activate testClass");
    }

    @Override
    public void doSimpleAdd(int x, int y) {
        System.out.println("Result(TestClass): " + (x + y));
    }

    @Override
    public void doSimpleSubstract(int x, int y) {
        System.out.println("Result(TestClass): " + (x - y));
    }
}

注册组件MyProvider和服务test.SimpleMathI(listed in karaf

这是消费者:

如果我没有引用服务SimpleMathI,但只有ConfigurationAdmin它可以正常工作!

package test;

import org.osgi.framework.BundleContext;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;

@Component (name = "MyConsumer", immediate = true, configurationPolicy = ConfigurationPolicy.OPTIONAL)
public class TestClass2 {

    public TestClass2() {
        System.out.println("contructing TestClass2");
    }

    @Reference (bind = "bind", unbind = "unbind")
    ConfigurationAdmin cm; // works

    @Reference (bind = "bindSimpleMathI", unbind = "unbindSimpleMathI")
    SimpleMathI simpleMath; // does not work, see screenshot

    @Activate
    protected void activate(ComponentContext c, BundleContext b) {
        System.out.println("activate testClass2");
        // simpleMath.doSimpleAdd(20, 25);
    }

    @Deactivate
    protected void deactivate() {
        System.out.println("de-activate testClass2");
    }

    protected void bind(ConfigurationAdmin a) {
        System.out.println("binding");
    }

    protected void unbind(ConfigurationAdmin a) {
        System.out.println("un-binding");
    }

    protected void bindSimpleMathI(SimpleMathI a) {
        System.out.println("binding!!");
    }

    protected void unbindSimpleMathI(SimpleMathI a) {
        System.out.println("un-binding!!");
    }
}

,这是Karaf webconsole中的输出。

我用Google搜索了足够的内容,但仍然无法弄清楚我错过了什么。奇怪,因为代码非常简单透明。那么,我实施了错误的提供者或消费者呢?

Karaf 4.0.7,没有使用Apache felix,纯OSGi R6声明服务

2 个答案:

答案 0 :(得分:0)

我认为你做了一个简单的错误。在OSGi中,您不应该有两个包含相同包的包。

OSGi中的典型设置是有三个包:

  • test.api for Interface
  • test.impl或test.provider for service impl
  • some.other.package for your consumer class

您可以将test.api和test.impl放在同一个包中,也可以使用单独的api包。

在任何情况下,消费者都不应该将接口包嵌入到自己的包中。相反,它应该在apife包的Manifest中有一个Import-Package。

答案 1 :(得分:0)

这是一个非常好的观点,并不知道。在我将使用者的包名更改为test2后,它仍然无法解析,因为它正在寻找带有test2.SimpleMathI的服务。

为了解决这个问题,我将包含测试的提供商的Eclipse项目导入到消费者的项目中,并在 pom.xml 依赖项中指定给提供者&# 39;捆绑:

<dependency>
    <groupId>com</groupId>
    <artifactId>DStestDS</artifactId>
    <version>0.0.18</version>
    <type>bundle</type>
</dependency>

并修改了消费者代码如下:

@Reference (bind = "bindSimpleMathI", unbind = "unbindSimpleMathI")
test.SimpleMathI simpleMath; 

但我不确定这是否正确......它以某种方式将我连接到这个特定的版本(18)。在manifest.mf我用来指定版本范围,如何在pom.xml中做到这一点?

wokring screenshot

谢谢Christian,你再次帮助了我。