Search code examples
javaosgimaven-2osgi-bundle

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


I'm completely new to OSGI framework and I'm trying to test below scenario with two bundle:

Bundle 1: I have created a OSGI bundle through maven using artifact group org.apache.karaf.archetypes. In bundle 1 activator class I'm registering a service as below:

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

Content of bundle 1 MANIFEST.MF file:

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

Bundle 2: I have created another independent bundle in the same way bundle 1 has been created. bundle 2 activator class is as below:

 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());
    
}

Content of bundle 2 MANIFEST.MF file:

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

Now i have installed both bundle in OSGI environment and when i am starting both bundle, bundle 1 is started properly while bundle 2 is throwing error as below:

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

I am having following doubt:

  1. Can you please let me know why bundle 2 is not getting deploy and how can I resolve it.

  2. Does each bundle Activator class object get unique BundleContext object. If so then how if once bundle is registering the class object with context object would be available for another bundle using context object.

  3. Does all the register objects to the OSGI environment is stored at one place which can be retrieved by any bundle deployed using context object or I have to use some other logic.


Solution

  • Your setup seems a bit confused? You're using an ancient version of bnd and the generated manifest does not seem to match expectations. bnd works from a bnd file or a pom manifest section, it is usually best to show these inputs.

    1 Unresolved

    The error happens because you've not properly exported/imported your packages.

                     Import-Package            Export-Package
    
    firstbundle      org.osgi.framework        com.osgi.learn.firstbundle
    secondbundle     com.osgi.learn.service    com.osgi.learn.secondbundle
                     org.osgi.framework
    

    When you start the secondbundle (6) you get the error that the package com.osgi.learn.service is not exported by any bundle, which matches the manifest information.

    So you need someone to export the com.osgi.learn.service package.

    2/3 Bundle Context & Service Registry

    Each bundle has its own unique Bundle Context object. This object has a getBundle() method that returns its unique Bundle object. However, the service registry is shared by all bundles. By registering and getting services through a Bundle specific BundleContext OSGi can do a lot of nice features like cleaning up, security, and more since OSGi knows the bundle that registers or gets the service.

    enter image description here

    You might want to get some OSGi experience by following the Bndtools OSGi starter guide, there are also lots of videos to show the different stages. This is based on Bndtools but once you got the experience it should not be hard to return to maven. If you still want, that is :-)