我是Java OSGi框架的新手。我在这里遵循一个示例教程:https://o7planning.org/en/10135/java-osgi-tutorial-for-beginners
我有一个提供基本数学函数的MathService捆绑包和一个使用MathService捆绑包的MathConsumer捆绑包。包从 MathService 捆绑包中正确导出,并为 MathConsumer 捆绑包正确设置了依赖项。
由于某种原因,MathConsumer Activator 中的 context.getServiceReference 调用返回 null,导致异常,我不明白为什么。以下是我的文件。有人有这方面的经验吗?
数学消费者激活剂.java :
package org.o7planning.tutorial.helloosgi.mathconsumer;
import org.o7planning.tutorial.helloosgi.mathservice.MathService;
import org.o7planning.tutorial.helloosgi.utils.MathUtils;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public class Activator implements BundleActivator {
private static BundleContext context;
static BundleContext getContext() {
return context;
}
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
System.out.println("MathConsumer Starting...");
System.out.println("5-3 = " + MathUtils.minus(5, 3));
//
ServiceReference<?> serviceReference=context.getServiceReference(MathService.class);
if (serviceReference == null) {
System.out.println("serviceReference is null"); // THE PROBLEM IS HERE
}
MathService service = (MathService)context.getService(serviceReference);
if (service == null) {
System.out.println("MathService service is null");
}
System.out.println("Got Mathservice service");
System.out.println("5+3 = " + service.sum(5, 3));
System.out.println("MathConsumer Started");
}
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
System.out.println("MathConsumer Stopped");
}
}
数学服务激活器.java
package org.o7planning.tutorial.helloosgi;
import org.o7planning.tutorial.helloosgi.mathservice.MathService;
import org.o7planning.tutorial.helloosgi.mathservice.impl.MathServiceImpl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator {
private static BundleContext context;
static BundleContext getContext() {
return context;
}
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
System.out.println("Registry Service MathService...");
this.registryMathService();
System.out.println("OSGi MathService Started");
}
private void registryMathService() {
MathService service = new MathServiceImpl();
context.registerService(MathService.class, service, null);
}
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
System.out.println("OSGi MathService Stopped!");
}
}
该教程是一个古老的教程。我强烈建议忘记它。
该代码存在许多问题,最大的问题是:
- 代码在捆绑包启动时仅执行一次。这违背了提供服务的目的。
- 不能保证
MathService
会在MathConsumer
之前启动,因此在请求服务时服务不可用 (null( 是完全可以的。
如果您绝对需要在激活器中执行此操作,那么您应该查看 ServiceTracker 并从线程调用该服务,该线程可以等待服务注册而不会阻止激活器。
但是,使用注释的声明性服务有更简单的方法可以做到这一点。
如果你只是想学习OSGi,我建议从enRoute开始。