环境
Version: Luna Service Release 2 (4.4.2)
故障
创建hello world的例子,参见
《eclipse编写OSGI入门例子 helloworld》章节《3. OSGi服务》 中的步骤,包括配置运行时依赖的5个Target Platform:
现象,空指针,HelloWorldBundle引用的接口实例为空:
Hello World!!
!SESSION 2020-10-23 14:32:09.141 -----------------------------------------------
eclipse.buildId=unknown
java.version=1.8.0_221
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=zh_CN
Command-line arguments: -dev file:D:/workspace/vcn/.metadata/.plugins/org.eclipse.pde.core/New_configuration/dev.properties -os win32 -ws win32 -arch x86 -consoleLog -console
!ENTRY HelloWorldBundle 4 0 2020-10-23 14:32:10.106
!MESSAGE FrameworkEvent ERROR
!STACK 0
org.osgi.framework.BundleException: Exception in helloworldbundle.Activator.start() of bundle HelloWorldBundle.
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:792)
at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:721)
at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:936)
at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:319)
at org.eclipse.osgi.container.Module.doStart(Module.java:571)
at org.eclipse.osgi.container.Module.start(Module.java:439)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1582)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1562)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1533)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1476)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
Caused by: java.lang.NullPointerException: A null service reference is not allowed.
at org.eclipse.osgi.internal.framework.BundleContextImpl.getService(BundleContextImpl.java:617)
at helloworldbundle.Activator.start(Activator.java:16)
at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:771)
at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:764)
... 12 more
Root exception:
java.lang.NullPointerException: A null service reference is not allowed.
at org.eclipse.osgi.internal.framework.BundleContextImpl.getService(BundleContextImpl.java:617)
at helloworldbundle.Activator.start(Activator.java:16)
at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:771)
at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:764)
at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:721)
at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:936)
at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:319)
at org.eclipse.osgi.container.Module.doStart(Module.java:571)
at org.eclipse.osgi.container.Module.start(Module.java:439)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1582)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1562)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1533)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1476)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
!ENTRY org.eclipse.osgi 4 0 2020-10-23 14:32:10.239
!MESSAGE Bundle HelloWorldBundle_1.0.0.qualifier [7] is not active.
查看bundle状态:
在这里插入代码片osgi> ss
"Framework is launched."
id State Bundle
0 ACTIVE org.eclipse.osgi_3.10.2.v20150203-1939
2 ACTIVE org.apache.felix.gogo.command_0.10.0.v201209301215
3 ACTIVE org.eclipse.equinox.console_1.1.0.v20140131-1639
4 ACTIVE org.apache.felix.gogo.runtime_0.10.0.v201209301036
5 ACTIVE org.apache.felix.gogo.shell_0.10.0.v201212101605
7 `RESOLVED` `HelloWorldBundle`_1.0.0.qualifier
8 `ACTIVE` `HelloServiceBundle`_1.0.0.qualifier
osgi>
定位结论
应该是bundle之间启动顺序引起的,HelloWorldBundle依赖HelloServiceBundle,我们默认启动时,bundle的优先级都是default,即值为0,但是我们发现"org.eclipse.osig"的优先级是"-1",初步猜测值越小,优先级越高,因此,我们把HelloWorldBundle改为6,让其优先级低于HelloServiceBundle,上面的截图已经高亮显示了。