OSGi Getting Started

By Michael N. Lipp

View GitHub Project

Introduction

Part 1: The container

Part 2: Simplest Bundle

Part 3: Simple Bundle

Part 4: Eclipse (OSGi) Plugin

Part 5: Bndtools

Part 6: Shift in Perspective

Part 7: Accessing a Service

Part 8: Tracking a Service

Part 9: Using a Service

Interlude: Cleaning up

Part 10: Service Component

The Container

In the simplest case of component based development, the components are assembled using some static configuration. More advanced concepts introduce a container as execution environment and allow you to dynamically add or remove components at runtime.

In OSGi terms, the container is provided by the OSGi framework and the components are provided by OSGi (compliant) bundles1. So in order to get started with OSGi, we need an OSGi framework. There are several implementations of the framework available. Let’s use Apache Felix to get started, because I found that to be very intuitive and easy to use.

I won’t repeat things here that have already been well described by others. So simply go to the Apache Felix Framework Usage Documentation and follow it up to and including the section “Starting the framework”. Make sure to only download the Felix Framework Distribution and none of the subprojects (yet).

After starting the framework, type “felix:lb” (short for “list bundles”) and you’ll get something like this:

START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.4.0)|5.4.0
    1|Active     |    1|Apache Felix Bundle Repository (2.0.6)|2.0.6
    2|Active     |    1|Apache Felix Gogo Command (0.16.0)|0.16.0
    3|Active     |    1|Apache Felix Gogo Runtime (0.16.2)|0.16.2
    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)|0.10.0

An “empty” OSGi runtime environment doesn’t seem to be really empty. It already contains some bundles. As we can guess from the “Level” it’s maybe not really necessary to have the “Apache Felix …” bundles, but most likely we need the “System bundle”.

Let’s see if we can find out a bit more about that bundle. Type “felix:headers 0” and you get:

System Bundle (0)
-----------------
Bundle-Description = This bundle is system specific; it implements various system services.
Bundle-ManifestVersion = 2
Bundle-Name = System Bundle
Bundle-SymbolicName = org.apache.felix.framework
Bundle-Version = 5.4.0
Export-Package = org.osgi.dto; version="1.0.0", org.osgi.framework; version="1.8.0", org.osgi.framework.dto; version="1.8.0", org.osgi.framework.hooks.bundle; version="1.1.0", org.osgi.framework.hooks.resolver; version="1.0.0", org.osgi.framework.hooks.service; version="1.1.0", org.osgi.framework.hooks.weaving; version="1.1.0", org.osgi.framework.launch; version="1.2.0", org.osgi.framework.namespace; version="1.1.0", org.osgi.framework.startlevel; version="1.0.0", org.osgi.framework.startlevel.dto; version="1.0.0", org.osgi.framework.wiring; version="1.2.0", org.osgi.framework.wiring.dto; version="1.2.0", org.osgi.resource; version="1.0.0", org.osgi.resource.dto; version="1.0.0", org.osgi.service.packageadmin; version="1.2.0", org.osgi.service.resolver; version="1.0.0", org.osgi.service.startlevel; version="1.1.0", org.osgi.service.url; version="1.0.0", org.osgi.util.tracker; version="1.5.1", javax.accessibility; uses:="javax.swing.text"; version="0.0.0.1_008_JavaSE", javax.activation; version="0.0.0.1_008_JavaSE", javax.activity; version="0.0.0.1_008_JavaSE", javax.annotation.processing; uses:="javax.tools,javax.lang.model,javax.lang.model.element,javax.lang.model.util"; version="0.0.0.1_008_JavaSE", javax.annotation; version="0.0.0.1_008_JavaSE", javax.crypto.interfaces; uses:="javax.crypto.spec,javax.crypto"; version="0.0.0.1_008_JavaSE", javax.crypto.spec; uses:="javax.crypto"; version="0.0.0.1_008_JavaSE", javax.crypto; uses:="javax.crypto.spec"; version="0.0.0.1_008_JavaSE", javax.imageio.event; uses:="javax.imageio"; version="0.0.0.1_008_JavaSE", javax.imageio.metadata; uses:="org.w3c.dom,javax.imageio"; version="0.0.0.1_008_JavaSE", javax.imageio.plugins.bmp; uses:="javax.imageio"; version="0.0.0.1_008_JavaSE", javax.imageio.plugins.jpeg; uses:="javax.imageio"; version="0.0.0.1_008_JavaSE", javax.imageio.spi; uses:="javax.imageio.stream,javax.imageio,javax.imageio.metadata"; version="0.0.0.1_008_JavaSE", javax.imageio.stream; uses:="javax.imageio"; version="0.0.0.1_008_JavaSE", javax.imageio; uses:="javax.imageio.metadata,javax.imageio.stream,javax.imageio.spi,javax.imageio.event"; version="0.0.0.1_008_JavaSE", javax.jws.soap; version="0.0.0.1_008_JavaSE", javax.jws; version="0.0.0.1_008_JavaSE", javax.lang.model.element; uses:="javax.lang.model.type,javax.lang.model"; version="0.0.0.1_008_JavaSE", javax.lang.model.type; uses:="javax.lang.model.element,javax.lang.model"; version="0.0.0.1_008_JavaSE", javax.lang.model.util; uses:="javax.lang.model,javax.lang.model.element,javax.annotation.processing,javax.lang.model.type"; version="0.0.0.1_008_JavaSE", javax.lang.model; version="0.0.0.1_008_JavaSE", javax.management.loading; uses:="javax.management"; version="0.0.0.1_008_JavaSE", javax.management.modelmbean; uses:="javax.management,javax.management.loading"; version="0.0.0.1_008_JavaSE", javax.management.monitor; uses:="javax.management"; version="0.0.0.1_008_JavaSE", javax.management.openmbean; uses:="javax.management"; version="0.0.0.1_008_JavaSE", javax.management.relation; uses:="javax.management"; version="0.0.0.1_008_JavaSE", javax.management.remote.rmi; uses:="javax.management.remote,javax.security.auth,javax.management,javax.management.loading,javax.naming,javax.rmi.ssl,org.omg.CORBA,org.omg.CORBA_2_3.portable,org.omg.CORBA.portable,javax.rmi.CORBA,javax.rmi"; version="0.0.0.1_008_JavaSE", javax.management.remote; uses:="javax.security.auth,javax.management"; version="0.0.0.1_008_JavaSE", javax.management.timer; uses:="javax.management"; version="0.0.0.1_008_JavaSE", javax.management; uses:="javax.management.loading,javax.management.openmbean"; version="0.0.0.1_008_JavaSE", javax.naming.directory; uses:="javax.naming"; version="0.0.0.1_008_JavaSE", javax.naming.event; uses:="javax.naming,javax.naming.directory"; version="0.0.0.1_008_JavaSE", javax.naming.ldap; uses:="javax.naming,javax.naming.directory,javax.net.ssl,javax.naming.event"; version="0.0.0.1_008_JavaSE", javax.naming.spi; uses:="javax.naming,javax.naming.directory"; version="0.0.0.1_008_JavaSE", javax.naming; uses:="javax.naming.spi"; version="0.0.0.1_008_JavaSE", javax.net.ssl; uses:="javax.security.cert,javax.security.auth.x500,javax.net"; version="0.0.0.1_008_JavaSE", javax.net; version="0.0.0.1_008_JavaSE", javax.print.attribute.standard; uses:="javax.print.attribute"; version="0.0.0.1_008_JavaSE", javax.print.attribute; version="0.0.0.1_008_JavaSE", javax.print.event; uses:="javax.print,javax.print.attribute"; version="0.0.0.1_008_JavaSE", javax.print; uses:="javax.print.attribute,javax.print.event,javax.print.attribute.standard"; version="0.0.0.1_008_JavaSE", javax.rmi.CORBA; uses:="org.omg.CORBA,org.omg.CORBA_2_3.portable,org.omg.CORBA.portable,org.omg.SendingContext"; version="0.0.0.1_008_JavaSE", javax.rmi.ssl; uses:="javax.net,javax.net.ssl"; version="0.0.0.1_008_JavaSE", javax.rmi; uses:="org.omg.CORBA,javax.rmi.CORBA"; version="0.0.0.1_008_JavaSE", javax.script; version="0.0.0.1_008_JavaSE", javax.security.auth.callback; version="0.0.0.1_008_JavaSE", javax.security.auth.kerberos; uses:="javax.security.auth,javax.crypto"; version="0.0.0.1_008_JavaSE", javax.security.auth.login; uses:="javax.security.auth,javax.security.auth.callback"; version="0.0.0.1_008_JavaSE", javax.security.auth.spi; uses:="javax.security.auth.callback,javax.security.auth.login,javax.security.auth"; version="0.0.0.1_008_JavaSE", javax.security.auth.x500; uses:="javax.security.auth"; version="0.0.0.1_008_JavaSE", javax.security.auth; version="0.0.0.1_008_JavaSE", javax.security.cert; version="0.0.0.1_008_JavaSE", javax.security.sasl; uses:="javax.security.auth.callback"; version="0.0.0.1_008_JavaSE", javax.sound.midi.spi; uses:="javax.sound.midi"; version="0.0.0.1_008_JavaSE", javax.sound.midi; uses:="javax.sound.midi.spi"; version="0.0.0.1_008_JavaSE", javax.sound.sampled.spi; uses:="javax.sound.sampled"; version="0.0.0.1_008_JavaSE", javax.sound.sampled; uses:="javax.sound.sampled.spi"; version="0.0.0.1_008_JavaSE", javax.sql.rowset.serial; uses:="javax.sql.rowset"; version="0.0.0.1_008_JavaSE", javax.sql.rowset.spi; uses:="javax.sql,javax.naming,javax.sql.rowset"; version="0.0.0.1_008_JavaSE", javax.sql.rowset; uses:="javax.sql,javax.sql.rowset.serial,javax.sql.rowset.spi"; version="0.0.0.1_008_JavaSE", javax.sql; uses:="javax.transaction.xa"; version="0.0.0.1_008_JavaSE", javax.swing.border; uses:="javax.swing"; version="0.0.0.1_008_JavaSE", javax.swing.colorchooser; uses:="javax.swing,javax.swing.border,javax.swing.event,javax.swing.text"; version="0.0.0.1_008_JavaSE", javax.swing.event; uses:="javax.swing,javax.swing.text,javax.swing.table,javax.swing.tree,javax.swing.undo"; version="0.0.0.1_008_JavaSE", javax.swing.filechooser; uses:="javax.swing"; version="0.0.0.1_008_JavaSE", javax.swing.plaf.basic; uses:="javax.swing.border,javax.swing,javax.swing.plaf,javax.swing.text,javax.swing.event,javax.swing.colorchooser,javax.accessibility,javax.swing.filechooser,javax.swing.text.html,javax.sound.sampled,javax.swing.table,javax.swing.plaf.synth,javax.swing.tree"; version="0.0.0.1_008_JavaSE", javax.swing.plaf.metal; uses:="javax.swing.plaf,javax.swing,javax.swing.border,javax.swing.text,javax.swing.plaf.basic,javax.swing.filechooser,javax.swing.event,javax.swing.tree"; version="0.0.0.1_008_JavaSE", javax.swing.plaf.multi; uses:="javax.accessibility,javax.swing,javax.swing.plaf,javax.swing.filechooser,javax.swing.text,javax.swing.tree"; version="0.0.0.1_008_JavaSE", javax.swing.plaf.nimbus; uses:="javax.swing,javax.swing.plaf,javax.swing.border,javax.swing.plaf.synth"; version="0.0.0.1_008_JavaSE", javax.swing.plaf.synth; uses:="javax.swing,javax.swing.plaf,javax.swing.text,javax.swing.border,javax.swing.plaf.basic,javax.swing.colorchooser,javax.swing.event,javax.xml.parsers,org.xml.sax,org.xml.sax.helpers,javax.swing.table,javax.swing.tree"; version="0.0.0.1_008_JavaSE", javax.swing.plaf; uses:="javax.swing,javax.swing.border,javax.accessibility,javax.swing.filechooser,javax.swing.text,javax.swing.tree"; version="0.0.0.1_008_JavaSE", javax.swing.table; uses:="javax.swing.event,javax.swing.plaf,javax.swing.border,javax.swing,javax.accessibility"; version="0.0.0.1_008_JavaSE", javax.swing.text.html.parser; uses:="javax.swing.text,javax.swing.text.html"; version="0.0.0.1_008_JavaSE", javax.swing.text.html; uses:="javax.swing.event,javax.swing.text,javax.accessibility,javax.swing,javax.swing.plaf,javax.swing.border,javax.swing.undo"; version="0.0.0.1_008_JavaSE", javax.swing.text.rtf; uses:="javax.swing.text"; version="0.0.0.1_008_JavaSE", javax.swing.text; uses:="javax.swing.event,javax.swing.tree,javax.swing.undo,javax.swing,javax.swing.plaf,javax.swing.plaf.basic,javax.print,javax.print.attribute,javax.accessibility,javax.swing.text.html"; version="0.0.0.1_008_JavaSE", javax.swing.tree; uses:="javax.swing.event,javax.swing,javax.swing.border,javax.swing.plaf,javax.swing.plaf.basic"; version="0.0.0.1_008_JavaSE", javax.swing.undo; uses:="javax.swing,javax.swing.event"; version="0.0.0.1_008_JavaSE", javax.swing; uses:="javax.swing.event,javax.accessibility,javax.swing.text,javax.swing.plaf,javax.swing.border,javax.swing.tree,javax.swing.table,javax.swing.colorchooser,javax.swing.plaf.basic,javax.swing.text.html,javax.swing.filechooser,javax.print,javax.print.attribute,javax.swing.plaf.metal"; version="0.0.0.1_008_JavaSE", javax.tools; uses:="javax.lang.model.element,javax.annotation.processing,javax.lang.model"; version="0.0.0.1_008_JavaSE", javax.transaction.xa; version="0.0.0.1_008_JavaSE", javax.transaction; version="0.0.0.1_008_JavaSE", javax.xml.bind.annotation.adapters; uses:="javax.xml.bind"; version="0.0.0.1_008_JavaSE", javax.xml.bind.annotation; uses:="javax.xml.transform,javax.xml.bind,javax.xml.parsers,javax.xml.transform.dom,org.w3c.dom"; version="0.0.0.1_008_JavaSE", javax.xml.bind.attachment; uses:="javax.activation"; version="0.0.0.1_008_JavaSE", javax.xml.bind.helpers; uses:="javax.xml.bind.annotation.adapters,javax.xml.transform.dom,org.w3c.dom,org.xml.sax,javax.xml.bind.attachment,javax.xml.stream,javax.xml.transform,javax.xml.transform.stream,javax.xml.validation,javax.xml.transform.sax,javax.xml.bind,javax.xml.parsers"; version="0.0.0.1_008_JavaSE", javax.xml.bind.util; uses:="javax.xml.transform.sax,javax.xml.bind,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers"; version="0.0.0.1_008_JavaSE", javax.xml.bind; uses:="javax.xml.validation,javax.xml.namespace,javax.xml.datatype,javax.xml.transform,javax.xml.bind.annotation,javax.xml.transform.stream,org.w3c.dom,javax.xml.bind.attachment,javax.xml.stream,javax.xml.bind.annotation.adapters,org.xml.sax"; version="0.0.0.1_008_JavaSE", javax.xml.crypto.dom; uses:="javax.xml.crypto,org.w3c.dom"; version="0.0.0.1_008_JavaSE", javax.xml.crypto.dsig.dom; uses:="javax.xml.crypto.dsig,javax.xml.crypto,org.w3c.dom,javax.xml.crypto.dom"; version="0.0.0.1_008_JavaSE", javax.xml.crypto.dsig.keyinfo; uses:="javax.xml.crypto"; version="0.0.0.1_008_JavaSE", javax.xml.crypto.dsig.spec; uses:="javax.xml.crypto"; version="0.0.0.1_008_JavaSE", javax.xml.crypto.dsig; uses:="javax.xml.crypto,javax.xml.crypto.dsig.spec,javax.xml.crypto.dsig.keyinfo"; version="0.0.0.1_008_JavaSE", javax.xml.crypto; uses:="javax.xml.crypto.dsig.keyinfo"; version="0.0.0.1_008_JavaSE", javax.xml.datatype; uses:="javax.xml.namespace"; version="0.0.0.1_008_JavaSE", javax.xml.namespace; version="0.0.0.1_008_JavaSE", javax.xml.parsers; uses:="javax.xml.validation,org.w3c.dom,org.xml.sax,org.xml.sax.helpers"; version="0.0.0.1_008_JavaSE", javax.xml.soap; uses:="javax.activation,javax.xml.namespace,org.w3c.dom,javax.xml.transform.dom,javax.xml.transform"; version="0.0.0.1_008_JavaSE", javax.xml.stream.events; uses:="javax.xml.namespace,javax.xml.stream"; version="0.0.0.1_008_JavaSE", javax.xml.stream.util; uses:="javax.xml.stream,javax.xml.stream.events,javax.xml.namespace"; version="0.0.0.1_008_JavaSE", javax.xml.stream; uses:="javax.xml.stream.events,javax.xml.namespace,javax.xml.stream.util,javax.xml.transform"; version="0.0.0.1_008_JavaSE", javax.xml.transform.dom; uses:="javax.xml.transform,org.w3c.dom"; version="0.0.0.1_008_JavaSE", javax.xml.transform.sax; uses:="org.xml.sax.ext,javax.xml.transform,org.xml.sax,javax.xml.transform.stream"; version="0.0.0.1_008_JavaSE", javax.xml.transform.stax; uses:="javax.xml.stream,javax.xml.transform,javax.xml.stream.events"; version="0.0.0.1_008_JavaSE", javax.xml.transform.stream; uses:="javax.xml.transform"; version="0.0.0.1_008_JavaSE", javax.xml.transform; version="0.0.0.1_008_JavaSE", javax.xml.validation; uses:="org.w3c.dom.ls,javax.xml.transform,javax.xml.transform.stream,org.xml.sax,org.w3c.dom"; version="0.0.0.1_008_JavaSE", javax.xml.ws.handler.soap; uses:="javax.xml.ws.handler,javax.xml.namespace,javax.xml.soap,javax.xml.bind"; version="0.0.0.1_008_JavaSE", javax.xml.ws.handler; uses:="javax.xml.ws,javax.xml.namespace"; version="0.0.0.1_008_JavaSE", javax.xml.ws.http; uses:="javax.xml.ws"; version="0.0.0.1_008_JavaSE", javax.xml.ws.soap; uses:="javax.xml.ws.spi,javax.xml.ws,javax.xml.soap"; version="0.0.0.1_008_JavaSE", javax.xml.ws.spi.http; version="0.0.0.1_008_JavaSE", javax.xml.ws.spi; uses:="javax.xml.ws,javax.xml.ws.wsaddressing,javax.xml.transform,org.w3c.dom,javax.xml.namespace,javax.xml.ws.handler,javax.xml.bind"; version="0.0.0.1_008_JavaSE", javax.xml.ws.wsaddressing; uses:="javax.xml.bind.annotation,javax.xml.namespace,org.w3c.dom,javax.xml.transform,javax.xml.bind,javax.xml.ws,javax.xml.ws.spi"; version="0.0.0.1_008_JavaSE", javax.xml.ws; uses:="javax.xml.ws.handler,javax.xml.ws.spi,javax.xml.ws.spi.http,javax.xml.transform,org.w3c.dom,javax.xml.bind.annotation,javax.xml.transform.stream,javax.xml.bind,javax.xml.namespace"; version="0.0.0.1_008_JavaSE", javax.xml.xpath; uses:="org.xml.sax,javax.xml.namespace"; version="0.0.0.1_008_JavaSE", javax.xml; version="0.0.0.1_008_JavaSE", org.ietf.jgss; version="0.0.0.1_008_JavaSE", org.omg.CORBA.DynAnyPackage; uses:="org.omg.CORBA"; version="0.0.0.1_008_JavaSE", org.omg.CORBA.ORBPackage; uses:="org.omg.CORBA"; version="0.0.0.1_008_JavaSE", org.omg.CORBA.TypeCodePackage; uses:="org.omg.CORBA"; version="0.0.0.1_008_JavaSE", org.omg.CORBA.portable; uses:="org.omg.CORBA,org.omg.CORBA_2_3.portable"; version="0.0.0.1_008_JavaSE", org.omg.CORBA; uses:="org.omg.CORBA.portable,org.omg.CORBA.DynAnyPackage,org.omg.CORBA.ORBPackage,org.omg.CORBA_2_3.portable,org.omg.CORBA.TypeCodePackage"; version="0.0.0.1_008_JavaSE", org.omg.CORBA_2_3.portable; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.CORBA_2_3; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.CosNaming.NamingContextExtPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.CosNaming.NamingContextPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.CosNaming"; version="0.0.0.1_008_JavaSE", org.omg.CosNaming; uses:="org.omg.CORBA.portable,org.omg.CORBA,org.omg.PortableServer,org.omg.CosNaming.NamingContextPackage,org.omg.CosNaming.NamingContextExtPackage"; version="0.0.0.1_008_JavaSE", org.omg.Dynamic; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.DynamicAny.DynAnyFactoryPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.DynamicAny.DynAnyPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.DynamicAny; uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.DynamicAny.DynAnyFactoryPackage,org.omg.DynamicAny.DynAnyPackage"; version="0.0.0.1_008_JavaSE", org.omg.IOP.CodecFactoryPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.IOP.CodecPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.IOP; uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.IOP.CodecFactoryPackage,org.omg.IOP.CodecPackage"; version="0.0.0.1_008_JavaSE", org.omg.Messaging; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.PortableInterceptor.ORBInitInfoPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.PortableInterceptor; uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.IOP,org.omg.PortableInterceptor.ORBInitInfoPackage,org.omg.CORBA_2_3.portable,org.omg.Dynamic"; version="0.0.0.1_008_JavaSE", org.omg.PortableServer.CurrentPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.PortableServer.POAManagerPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.PortableServer.POAPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.PortableServer.ServantLocatorPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.PortableServer.portable; uses:="org.omg.CORBA,org.omg.PortableServer"; version="0.0.0.1_008_JavaSE", org.omg.PortableServer; uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.PortableServer.CurrentPackage,org.omg.PortableServer.POAManagerPackage,org.omg.PortableServer.POAPackage,org.omg.PortableServer.portable,org.omg.CORBA_2_3,org.omg.PortableServer.ServantLocatorPackage"; version="0.0.0.1_008_JavaSE", org.omg.SendingContext; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_008_JavaSE", org.omg.stub.java.rmi; uses:="javax.rmi.CORBA"; version="0.0.0.1_008_JavaSE", org.w3c.dom.bootstrap; uses:="org.w3c.dom"; version="0.0.0.1_008_JavaSE", org.w3c.dom.events; uses:="org.w3c.dom,org.w3c.dom.views"; version="0.0.0.1_008_JavaSE", org.w3c.dom.ls; uses:="org.w3c.dom,org.w3c.dom.events,org.w3c.dom.traversal"; version="0.0.0.1_008_JavaSE", org.w3c.dom; version="0.0.0.1_008_JavaSE", org.xml.sax.ext; uses:="org.xml.sax,org.xml.sax.helpers"; version="0.0.0.1_008_JavaSE", org.xml.sax.helpers; uses:="org.xml.sax"; version="0.0.0.1_008_JavaSE", org.xml.sax; version="0.0.0.1_008_JavaSE"
Export-Service = org.osgi.service.packageadmin.PackageAdmin,org.osgi.service.startlevel.StartLevel,org.osgi.service.url.URLHandlers
Provide-Capability = osgi.service; objectClass:List<String>=org.osgi.service.resolver.Resolver; uses:=org.osgi.service.resolver, osgi.service; objectClass:List<String>=org.osgi.service.startlevel.StartLevel; uses:=org.osgi.service.startlevel, osgi.service; objectClass:List<String>=org.osgi.service.packageadmin.PackageAdmin; uses:=org.osgi.service.packageadmin, osgi.ee; osgi.ee="OSGi/Minimum"; version:List<Version>="1.0,1.1,1.2", osgi.ee; osgi.ee="JavaSE"; version:List<Version>="1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8", osgi.ee; osgi.ee="JavaSE/compact1"; version:List<Version>="1.8", osgi.ee; osgi.ee="JavaSE/compact2"; version:List<Version>="1.8", osgi.ee; osgi.ee="JavaSE/compact3"; version:List<Version>="1.8"

Looks like there is a lot of information associated with a bundle and maybe that’s why people consider bundles to be difficult to build. But most of that information is optional. In part 2, we’ll see that it is really easy to build a (simple) bundle.


  1. An OSGi bundle is actually only a module. It can be a component if it fulfills some additional constraints. However, as OSGi also provides support for components, OSGi is often presented as a component framework rather than a module framework. The tons of introductions that focus on a runtime environment such as Felix emphasize that angle. I stumbled upon OSGi while searching for a component framework myself, and if you are still reading this, chances are high that you you are also thinking about components, so let’s stick to that view for the first parts of this introduction.