对 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,你又帮了我。
我有一个非常简单的服务提供者和消费者。出于某种原因,我无法解决我的消费者使用提供商服务的问题。 这是提供商的捆绑包源代码:
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,你又帮了我。