对 Karaf 中的服务表示不满意(参考) - 错误在哪里? (OSGi、声明式服务、注解)

State unsatisfied (reference) for service in Karaf - where is the mistake? (OSGi, declarative service, annotations)

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

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 声明式服务

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

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

  • test.api 接口
  • test.impl 或 test.provider 用于服务实现
  • some.other.package 为您的消费者 class

您可以将 test.api 和 test.impl 放在同一个捆绑包中,或者有一个单独的 api 捆绑包。

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

这是一个很好的观点,不知道。在我将消费者的包名称更改为 test2 后,它仍然无法解析,因为它正在寻找 test2.SimpleMathI.

的服务

为了解决这个问题,我将提供商的 Eclipse 项目和包 test 导入到消费者的项目中,并在 pom.xml 依赖项中指定到提供商的捆绑包:

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

并修改consumer代码如下:

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

但我不确定这是否正确...它以某种方式将我与这个特定版本 (18) 联系起来。在manifest.mf中我曾经指定版本范围,在pom.xml中如何做到?

wokring screenshot

谢谢Christian,你又帮了我。