部署在 OSGI 框架中的每个 bundle 是否都有自己的 bundleContext 对象?

Does each bundle deployed in OSGI framework has it's own bundleContext object?

我是 OSGI 框架的新手,我正在尝试使用两个包测试以下场景:

捆绑包 1: 我已经使用工件组 org.apache.karaf.archetypes. 通过 Maven 创建了一个 OSGI 包 在 bundle 1 activator class 中,我正在注册如下服务:

 public void start(BundleContext context) {
        System.out.println("-------------- Starting firstbundle ----------------");
        context.registerService(EmployeeService.class, new EmployeeServiceImpl(), null);
    }

捆绑包 1 MANIFEST.MF 文件的内容:

Manifest-Version: 1.0
Bnd-LastModified: 1594906982858
Build-Jdk: 1.8.0_251
Built-By: 212807091
Bundle-Activator: com.osgi.learn.firstbundle.Activator
Bundle-Description: firstbundle OSGi bundle project.
Bundle-ManifestVersion: 2
Bundle-Name: firstbundle Bundle
Bundle-SymbolicName: firstbundle
Bundle-Version: 0.0.1.SNAPSHOT
Created-By: Apache Maven Bundle Plugin
Export-Package: com.osgi.learn.firstbundle;version="0.0.1.SNAPSHOT";uses
 :="org.osgi.framework"
Import-Package: org.osgi.framework;version="[1.7,2)"
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Tool: Bnd-2.3.0.201405100607

捆绑包 2: 我以创建 bundle 1 的相同方式创建了另一个独立的 bundle。 bundle 2 activator class 如下:

 public void start(BundleContext context) {
        ServiceReference<?>  ref = context.getServiceReference(EmployeeService.class);
        EmployeeService empService = (EmployeeService) context.getService(ref);
        boolean isRegister = empService.register("rohit", "rohit");
        if(isRegister){
            System.out.println("employee registered successfully");
        } else{
            System.out.println("employe is already registered");
        }
    System.out.println("after register employee list: "+empService.getEmployeeList().size());
    
}

包 2 MANIFEST.MF 文件的内容:

Manifest-Version: 1.0
Bnd-LastModified: 1594907276585
Build-Jdk: 1.8.0_251
Built-By: 212807091
Bundle-Activator: com.osgi.learn.secondbundle.Activator
Bundle-Description: secondbundle OSGi bundle project.
Bundle-ManifestVersion: 2
Bundle-Name: secondbundle Bundle
Bundle-SymbolicName: secondbundle
Bundle-Version: 0.0.1.SNAPSHOT
Created-By: Apache Maven Bundle Plugin
Export-Package: com.osgi.learn.secondbundle;version="0.0.1.SNAPSHOT";use
 s:="org.osgi.framework"
Import-Package: com.osgi.learn.service,org.osgi.framework;version="[1.7,
 2)"
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Tool: Bnd-2.3.0.201405100607

现在我已经在 OSGI 环境中安装了这两个包,当我启动这两个包时,包 1 正确启动而包 2 抛出如下错误:

osgi> ss
"Framework is launched."


id  State       Bundle
0   ACTIVE      org.eclipse.osgi_3.11.3.v20170209-1843
1   ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036
2   ACTIVE      org.eclipse.equinox.console_1.1.200.v20150929-1405
3   ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605
4   ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215
5   INSTALLED   firstbundle_0.0.1.SNAPSHOT
6   INSTALLED   secondbundle_0.0.1.SNAPSHOT
osgi> start 5
-------------- Starting firstbundle ----------------
osgi> start 6
gogo: BundleException: Could not resolve module: secondbundle [6]
  Unresolved requirement: Import-Package: com.osgi.learn.service

我有以下疑问:

  1. 你能告诉我为什么 bundle 2 没有部署吗?我该如何解决它。

  2. 每个 bundle Activator class 对象是否获得唯一的 BundleContext 对象。如果是这样,那么如果一旦 bundle 正在使用上下文对象注册 class 对象将如何可用于另一个使用上下文对象的 bundle。

  3. OSGI 环境的所有注册对象是否都存储在一个地方,可以由使用上下文对象部署的任何包检索,或者我必须使用其他逻辑。

您的设置似乎有点混乱?您使用的是 bnd 的旧版本,生成的清单似乎与预期不符。 bnd 从 bnd 文件或 pom 清单部分工作,通常最好显示这些输入。

1 未解决

发生错误是因为您没有正确exported/imported您的包裹。

                 Import-Package            Export-Package

firstbundle      org.osgi.framework        com.osgi.learn.firstbundle
secondbundle     com.osgi.learn.service    com.osgi.learn.secondbundle
                 org.osgi.framework

当您启动 secondbundle (6) 时,您会收到错误消息,即包 com.osgi.learn.service 未被任何包导出,这与清单信息相匹配。

所以你需要有人导出 com.osgi.learn.service 包。

2/3 捆绑上下文和服务注册表

每个 bundle 都有自己独特的 Bundle Context 对象。该对象有一个 getBundle() 方法,该方法 return 是其唯一的 Bundle 对象。但是,服务注册表由所有捆绑包共享。通过 Bundle 特定的 BundleContext 注册和获取服务,OSGi 可以做很多不错的功能,比如清理、安全等等,因为 OSGi 知道注册或获取服务的 bundle。

您可能想通过遵循 Bndtools OSGi starter guide, there are also lots of videos 来显示不同的阶段来获得一些 OSGi 经验。这是基于 Bndtools 的,但是一旦你有了经验,return 到 maven 应该不难。如果你还想要,那就是:-)