Friday, 26 June 2015

OSGi 101 - Create simple bundle (Equinox & Felix)

This is the last article about OSGi which I'm going to write (for now). We already discussed the basics of Apache Felix and Eclipse Equinox. We know how to run these OSGi engines and we covered some of the commands we can use in the OSGi console.

Now it's time to fulfil the cycle and create our own OSGi bundle. This is not supposed to be another OSGi tutorial - I'll just show you step by step how to compile & build the bundle and how to work with it in the OSGI console.

Let's begin!

First of all we need some code. Here it goes - Activator.java:

package sampleosgi;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class Activator implements BundleActivator {
  
  @Override
  public void start(BundleContext context) throws Exception {
    System.out.println("Hello World!!");
  }

  @Override
  public void stop(BundleContext context) throws Exception {
    System.out.println("Goodbye World!!");
  }

}

When we start our OSGi bundle the start(...) method will be executed. And when we stop our OSGi bundle the stop(...) method will be executed. That's all. No other fancy stuff.

Probably you are wondering about the package org.osgi.framework - we'll talk more about it later.

Apart from the source code, we also need a manifest file. All OSGi bundles are plain old JAR files with one or more OSGi specific manifest headers. Here is the manifest file META-INF/MANIFEST.MF that we are going to use:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Sample OSGI Program
Bundle-SymbolicName: sample.osgi.program
Bundle-Version: 1.0.0.sample
Bundle-Activator: sampleosgi.Activator
Import-Package: org.osgi.framework

I'm not going to explain what these headers do. It's quite obvious and you can check the meaning of all OSGi headers here. The most important thing here is the Bundle-Activator header which points to our class which we haven't compiled yet. Another interesting thing to know is that the bundle's uniqueness in the OSGi environment is based on the combination of Bundle-SymbolicName and Bundle-Version. Our bundle has no dependencies on other bundles, apart from the default org.osgi.framework package which has been declared in the manifest headers.

Now it's time to compile the Activator class.

Compilation with Apache Felix


We need to add felix.jar to the classpath. After that the compilation process is straight forward. On my machine I use the following CMD file to automate the whole process:

rmdir /s /q bin
mkdir bin

javac -cp ..\felix-framework-5.0.1\bin\felix.jar -d .\bin src\sampleosgi\Activator.java

jar -cvmf .\src\META-INF\MANIFEST.MF .\osgi-sample-felix.jar -C .\bin\ .

Compilation with Eclipse Equinox


We need to add org.eclipse.osgi_3.10.100.v20150529-1857.jar to the classpath. After that the compilation process is straight forward. On my machine I use the following CMD file to automate the whole process:

rmdir /s /q bin
mkdir bin

javac -cp ..\equinox-SDK-Mars\plugins\org.eclipse.osgi_3.10.100.v20150529-1857.jar -d .\bin src\sampleosgi\Activator.java

jar -cvmf .\src\META-INF\MANIFEST.MF .\osgi-sample-equinox.jar -C .\bin\ .

Apache Felix - Install, Resolve, Start, Stop, Uninstall


On my machine the created bundle osgi-sample-felix.jar resides in the folder osgi\sample and again on my machine I have started Apache Felix from the folder osgi\felix-framework-5.0.1.

C:\Ivan\osgi\felix-framework-5.0.1>
C:\Ivan\osgi\felix-framework-5.0.1>java -jar bin\felix.jar
____________________________
Welcome to Apache Felix Gogo

g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.0.1)
    1|Active     |    1|Apache Felix Bundle Repository (2.0.4)
    2|Active     |    1|Apache Felix Gogo Command (0.14.0)
    3|Active     |    1|Apache Felix Gogo Runtime (0.16.2)
    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)
g! install file:../sample/osgi-sample-felix.jar
Bundle ID: 10
g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.0.1)
    1|Active     |    1|Apache Felix Bundle Repository (2.0.4)
    2|Active     |    1|Apache Felix Gogo Command (0.14.0)
    3|Active     |    1|Apache Felix Gogo Runtime (0.16.2)
    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)
   10|Installed  |    1|Sample OSGI Program (1.0.0.sample)
g! resolve 10
g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.0.1)
    1|Active     |    1|Apache Felix Bundle Repository (2.0.4)
    2|Active     |    1|Apache Felix Gogo Command (0.14.0)
    3|Active     |    1|Apache Felix Gogo Runtime (0.16.2)
    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)
   10|Resolved   |    1|Sample OSGI Program (1.0.0.sample)
g! start 10
Hello World!!
g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.0.1)
    1|Active     |    1|Apache Felix Bundle Repository (2.0.4)
    2|Active     |    1|Apache Felix Gogo Command (0.14.0)
    3|Active     |    1|Apache Felix Gogo Runtime (0.16.2)
    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)
   10|Active     |    1|Sample OSGI Program (1.0.0.sample)
g! stop 10
Goodbye World!!
g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.0.1)
    1|Active     |    1|Apache Felix Bundle Repository (2.0.4)
    2|Active     |    1|Apache Felix Gogo Command (0.14.0)
    3|Active     |    1|Apache Felix Gogo Runtime (0.16.2)
    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)
   10|Resolved   |    1|Sample OSGI Program (1.0.0.sample)
g! uninstall 10
g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.0.1)
    1|Active     |    1|Apache Felix Bundle Repository (2.0.4)
    2|Active     |    1|Apache Felix Gogo Command (0.14.0)
    3|Active     |    1|Apache Felix Gogo Runtime (0.16.2)
    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)
g!

You can see what I've done and how I've done it. It's very, very simple! :)

Eclipse Equinox - Install, Refresh, Start, Stop, Uninstall


On my machine the created bundle osgi-sample-equinox.jar resides in the folder osgi\sample and again on my machine I have started Eclipse Equinox from the folder osgi\equinox-SDK-Mars.

This time the console output is much wider, so I'm going to use screenshots. First we want to see what's the current status of all bundles. We use the ss command.

Eclipse Equinox - ss
Eclipse Equinox - ss
Next we want to install our bundle. We use the install command. When we ss again, we see that our bundle has been installed.

Eclipse Equinox - install
Eclipse Equinox - install
In order to resolve the dependencise, we can use the refresh command. Or we can directly use the start command which will automatically try to resolve the dependencies. The same could have been done in Apache Felix but here we do the steps one by one in order to see the full picture.

After we have resolved the dependencies we use the start command in order to activate our OSGi bundle.

Eclipse Equinox - refresh and start
Eclipse Equinox - refresh and start
We use the stop command when we want to deactivate OSGi bundle. And we use the uninstall command in order to remove OSGi bundle.

Eclipse Equinox - stop and uninstall
Eclipse Equinox - stop and uninstall
And that's all. :)

By the way, you can install the Felix bundle in Equinox and vice versa. You can try it. However, you can't install both bundles in the same OSGi environment. That's because both bundles have the same symbolic name and the same version.

3 comments:

  1. Браво! По едно време и мислех и аз да пусна някакви уроци по OSGI, но ти си почнал :)

    ReplyDelete
  2. This is also a clear explanation.. Thank you again... If you have any experience about OSGI tools, a blog post related to suggestion of OSGI tools will be very useful for us.

    ReplyDelete