blob: 923a77bab7edde2a2c5843c59e183adf4550cce1 [file] [log] [blame]
<html><head><META http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>OSGi Concepts</title><meta content="DocBook XSL Stylesheets V1.76.0" name="generator"><link rel="home" href="index.html" title="Virgo User Guide"><link rel="up" href="ch02.html" title="Chapter&nbsp;2.&nbsp;Concepts"><link rel="prev" href="ch02.html" title="Chapter&nbsp;2.&nbsp;Concepts"><link rel="next" href="ch02s03.html" title="Spring DM and Blueprint Concepts"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table summary="Navigation header" width="100%"><tr><td align="left" width="20%"><a accesskey="p" href="ch02.html">Prev</a>&nbsp;</td><th align="center" width="60%">&nbsp;</th><td align="right" width="20%">&nbsp;<a accesskey="n" href="ch02s03.html">Next</a></td></tr></table><hr></div><div class="section" title="OSGi Concepts"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="concepts.osgi"></a>OSGi Concepts</h2></div></div></div><p>Modules in Virgo are represented using a standard Java
module system known as <span class="emphasis"><em>OSGi</em></span>.
Modules in OSGi are known as <span class="emphasis"><em>bundles</em></span>.
Bundles consist of programs and resources organised by Java package together
with metadata which declares imported and exported packages.
A bundle <span class="emphasis"><em>exports</em></span> a package to make the corresponding programs and resources
available for use by other bundles.
A bundle <span class="emphasis"><em>imports</em></span> a package to use the corresponding programs and resources of
another bundle.</p><p>
Representing a program as a collection of bundles makes it easier for the
programmer to manage it and modify it and for teams of programmers to divide
responsibilities between themselves.
A bundle is similar to a Java class in this respect. Design principles similar to those for
organising data and programs into classes can be applied
to organising applications into bundles.
</p><p>
An industry consortium known as the
<span class="emphasis"><em>OSGi Alliance</em></span> develops OSGi
specifications, reference implementations, and compliance tests.
Virgo is built on the Equinox OSGi framework which is also
the reference implementation for the OSGi framework specification.
</p><div class="section" title="Bundles"><div class="titlepage"><div><div><h3 class="title"><a name="N100B2"></a>Bundles</h3></div></div></div><p>
Each bundle is stored in a file which conforms to the JAR file format and
can contain Java classes, a manifest (in <code class="literal">META-INF/MANIFEST.MF</code>),
and further resource files.</p><p>The OSGi framework enables bundles to be installed and run.</p><p>OSGi identifies bundles <span class="quote">&ldquo;<span class="quote">by name</span>&rdquo;</span> and <span class="quote">&ldquo;<span class="quote">by identifier</span>&rdquo;</span> (id).</p><p>The <span class="emphasis"><em>symbolic name</em></span> and
<span class="emphasis"><em>version</em></span> of a bundle are attributes of the bundle which identify the bundle.
A bundle declares its <span class="emphasis"><em>symbolic name</em></span> and <span class="emphasis"><em>version</em></span>
in its manifest (a file called <code class="literal">MANIFEST.MF</code>) like this:
</p><pre class="programlisting">Bundle-SymbolicName: org.foo.bundle
Bundle-Version: 1.2.3.BUILD-2009-06-04
</pre><p>
</p><p>Additionally, the OSGi framework
assigns a distinct number, known as a <span class="emphasis"><em>bundle id</em></span>, to each bundle
as it is installed. Bundles may be referred to <span class="quote">&ldquo;<span class="quote">by identifier</span>&rdquo;</span> using this number.
The OSGi framework itself resides in a
bundle with bundle id <code class="literal">0</code>.</p><p>The
dependencies between bundles are expressed statically in terms of packages and
dynamically in terms of services. A package is familiar to Java programmers.
For example, a Java program may depend on a class <code class="literal">org.foo.X</code>,
from package <code class="literal">org.foo</code>, and a bundle
containing that program
would either need to contain <code class="literal">org.foo.X</code> or depend on the
package <code class="literal">org.foo</code>.
Package dependencies are specified in the bundle manifest, for example:
</p><pre class="programlisting">Import-Package: org.foo
</pre><p>
</p><p>A bundle which provides a package for use by other bundles <span class="emphasis"><em>must</em></span>
export the package in its manifest. For example:
</p><pre class="programlisting">Export-Package: org.foo
</pre><p>
</p><p>The OSGi framework ensures that a given bundle&rsquo;s package dependencies
can be <span class="emphasis"><em>satisfied</em></span> before the bundle runs. This process is known as
<span class="emphasis"><em>resolution</em></span>.</p><p>After a bundle is resolved, its classes and resources are available for
loading.
In OSGi, bundles and their packages do not appear on the application classpath.
Instead, each bundle has a class loader which loads its own classes and loads classes belonging to each of its
imported packages by deferring to the bundle class loader that exports the package.</p></div><div class="section" title="Life Cycle"><div class="titlepage"><div><div><h3 class="title"><a name="N10111"></a>Life Cycle</h3></div></div></div><p>The OSGi framework manages the <span class="emphasis"><em>life cycle</em></span> of each bundle. A bundle is
first of all <span class="emphasis"><em>install</em></span>ed and will be in the INSTALLED state.
If a request is made to <span class="emphasis"><em>start</em></span> the bundle, the OSGi framework <span class="emphasis"><em>resolve</em></span>s the bundle
and, if resolution was successful, will subsequently move the bundle to the ACTIVE state.
If a request is made to <span class="emphasis"><em>stop</em></span> the bundle, the OSGi framework will move the
bundle back to the RESOLVED state. A request may then be made to <span class="emphasis"><em>uninstall</em></span>
the bundle.</p><p>While the bundle is INSTALLED, ACTIVE or RESOLVED, it may be <span class="emphasis"><em>updated</em></span> to pick up
some changes. These changes are not detected by bundles which were depending
on the bundle before it was updated.
A <span class="quote">&ldquo;<span class="quote">refresh packages</span>&rdquo;</span> operation may be performed to ripple the
changes out to those bundles. (See <a class="xref" href="ch02s02.html#concepts.services" title="Services">Services concepts</a>.)</p><p>The life cycle of a bundle can be summarised by a state transition diagram.
This diagram shows some more of the intermediate states of a bundle not described in the overview above:
</p><div class="figure"><a name="N10135"></a><p class="title"><b>Figure&nbsp;2.1.&nbsp;Bundle life cycle</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="images/concepts/bundle-lifecycle.png" align="middle" alt="Bundle life cycle"></div></div></div><p><br class="figure-break"></p></div><div class="section" title="Services"><div class="titlepage"><div><div><h3 class="title"><a name="concepts.services"></a>Services</h3></div></div></div><p>Bundles may publish Java objects, known as <span class="emphasis"><em>services</em></span>,
to a registry managed by the OSGi framework. Other bundles running in
the same OSGi framework can then find and use those services. Services
are typically instances of some shared Java interface. A bundle which
provides a service need not then export the package containing the
<span class="emphasis"><em>implementation</em></span>
class of the service.
</p><p>For example, a bundle could export a package containing the interface
<code class="literal">org.bar.SomeInterface</code>, thus:
</p><pre class="programlisting">Export-Package: org.bar
</pre><p>
</p><p>???implement the interface with a class <code class="literal">SomeImpl</code>:
</p><pre class="programlisting">package org.bar.impl;
class SomeImpl implements SomeInterface {
???
}
</pre><p>
</p><p>???create an instance of <code class="literal">SomeImpl</code> and
then publish this instance (as an instance of the interface <code class="literal">SomeInterface</code>).
</p><p>An OSGi framework publishes a number of standard services. For example, the
<span class="emphasis"><em>Package Admin</em></span> service provides the <span class="quote">&ldquo;<span class="quote">refresh packages</span>&rdquo;</span> life cycle operation
mentioned above.</p><p>OSGi provides an <em class="glossterm">API</em> which can be used to publish and find services,
but it is much simpler to use Spring DM or Blueprint to accomplish this. (See <a class="xref" href="ch02s03.html" title="Spring DM and Blueprint Concepts">Spring DM concepts</a>.)</p></div><div class="section" title="Versioning"><div class="titlepage"><div><div><h3 class="title"><a name="N10184"></a>Versioning</h3></div></div></div><p>
OSGi allows different versions of bundles, packages, and several
other entities, to co-exist in the same framework
and provides some mechanisms for managing these versions.
</p><div class="section" title="Version Numbers"><div class="titlepage"><div><div><h4 class="title"><a name="N10189"></a>Version Numbers</h4></div></div></div><p>An OSGi <span class="emphasis"><em>version number</em></span> consists of up to three numeric components,
or exactly three
numeric components followed by a string component. These components are
separated by a period (<span class="quote">&ldquo;<span class="quote"><code class="literal">.</code></span>&rdquo;</span>) and
are called the <span class="emphasis"><em>major</em></span>, <span class="emphasis"><em>minor</em></span>, <span class="emphasis"><em>micro</em></span>,
and <span class="emphasis"><em>qualifier</em></span> components, respectively.
</p><p>For example, the version <code class="literal">2.4.1.ga</code> has major component <code class="literal">2</code>, minor component
<code class="literal">4</code>, micro component <code class="literal">1</code>,
and a qualifier component <code class="literal">ga</code>. (There are restrictions on the characters that can appear in
a qualifier. For example: letters, digits, underscores and hyphens are allowed; periods and commas are not.)</p><p>Trailing components may be omitted along with their period (<code class="literal">.</code>). So, for example, the version
numbers <code class="literal">2</code>, <code class="literal">2.0</code>, and <code class="literal">2.0.0</code>
all denote the same version. This example demonstrates that <code class="literal">0</code> is assumed if a numeric component is omitted,
and the empty string is assumed for an omitted qualifier.</p></div><div class="section" title="Version Ranges"><div class="titlepage"><div><div><h4 class="title"><a name="N101CE"></a>Version Ranges</h4></div></div></div><p>Dependencies on bundles and packages have an associated <span class="emphasis"><em>version range</em></span>
which is specified using an interval notation: a square bracket
<span class="quote">&ldquo;<span class="quote"><code class="literal">[</code></span>&rdquo;</span> or <span class="quote">&ldquo;<span class="quote"><code class="literal">]</code></span>&rdquo;</span> denotes
an <span class="emphasis"><em>inclusive</em></span> end of the range and a round bracket
<span class="quote">&ldquo;<span class="quote"><code class="literal">(</code></span>&rdquo;</span> or <span class="quote">&ldquo;<span class="quote"><code class="literal">)</code></span>&rdquo;</span> denotes
an <span class="emphasis"><em>exclusive</em></span> end of the range. Where one end of the range is to be included and the other excluded, it is permitted to
pair a round bracket with a square bracket.
The examples below make this clear.</p><p>If a single version number is used where a version <span class="emphasis"><em>range</em></span> is
required this does <span class="emphasis"><em>not</em></span> indicate a single version, but the range <span class="emphasis"><em>starting</em></span> from that version and
including all higher versions.</p><p>There are three common cases:
</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>A <span class="quote">&ldquo;<span class="quote">strict</span>&rdquo;</span> version range, such as <code class="literal">[1.2,1.2]</code>, which
denotes that version and only that version.</p></li><li class="listitem"><p>A <span class="quote">&ldquo;<span class="quote">half-open</span>&rdquo;</span> range, such as
<code class="literal">[1.2,2)</code>, which has an inclusive lower limit
and an exclusive upper limit, denoting version <code class="literal">1.2.0</code> and any version after this, up
to, <span class="emphasis"><em>but not including</em></span>, version <code class="literal">2.0.0</code>.
</p></li><li class="listitem"><p>An <span class="quote">&ldquo;<span class="quote">unbounded</span>&rdquo;</span> version range, such as <code class="literal">1.2</code>, which
denotes version <code class="literal">1.2</code> and <span class="emphasis"><em>all</em></span> later versions.</p></li></ul></div><p>
</p></div><div class="section" title="Versioning Policies"><div class="titlepage"><div><div><h4 class="title"><a name="N1022F"></a>Versioning Policies</h4></div></div></div><p>A <span class="emphasis"><em>versioning policy</em></span> is a way of using version numbers to indicate compatible
and incompatible changes.
OSGi does not mandate a particular versioning policy.
Instead, a specific versioning policy may be implemented using version ranges.</p><p>Strict and half-open version ranges are most useful in representing versioning
policies.
Unbounded version ranges can lead to problems as they (unrealistically) assume that
compatibility will be preserved indefinitely.</p><p>For example, a conservative versioning policy might assume that any change, other than
in the qualifier component of a version, implies an incompatible
change to the object.
Such a policy would employ version ranges such as <code class="literal">[1.2.1.beta,1.2.2)</code>
which accept any version from <code class="literal">1.2.1.beta</code> (inclusive) up to but not including
<code class="literal">1.2.2</code> (exclusive).
</p><p>Alternatively, a relaxed versioning policy might assume that only changes in the major component of
a version denote an incompatible change.
Such a policy would employ version ranges such as <code class="literal">[1.2,2)</code> to capture this.</p><p>
The OSGi Alliance has published a <a class="ulink" href="http://www.osgi.org/wiki/uploads/Links/SemanticVersioning.pdf" target="_top">Semantic
Versioning white paper</a> which provides some recommendations and guidance on versioning policies.
</p></div><div class="section" title="Bundle Version"><div class="titlepage"><div><div><h4 class="title"><a name="N10254"></a>Bundle Version</h4></div></div></div><p>Each bundle has a version.
The bundle&rsquo;s version may be specified in the manifest using a
<code class="literal">Bundle-Version</code> header:
</p><div class="informalexample"><pre class="programlisting">Bundle-Version: 1.4.3.BUILD-20090302
</pre></div><p>
If not specified the bundle version is assumed to be <code class="literal">0</code>.
</p></div><div class="section" title="Package Version"><div class="titlepage"><div><div><h4 class="title"><a name="N10267"></a>Package Version</h4></div></div></div><p>Each exported package has a version.
The exported package&rsquo;s version may be specified on the Export-Package manifest header. For example
</p><div class="informalexample"><pre class="programlisting">Export-Package: org.foo;version="2.9",org.bar;version="1"
</pre></div><p>
exports two packages: <code class="literal">org.foo</code>, at version <code class="literal">2.9.0</code> and
<code class="literal">org.bar</code>, at version <code class="literal">1.0.0</code>.
</p><p>If the version attribute is omitted, the version is assumed to be <code class="literal">0</code>.</p><p>Each package <span class="emphasis"><em>import</em></span> has a version <span class="emphasis"><em>range</em></span>.
The package import version range may be specified on the <code class="literal">Import-Package</code> manifest header.
If interval notation is used, the version range must be enclosed in double quotes, for example:
</p><div class="informalexample"><pre class="programlisting">Import-Package: org.foo;version="[2,3)",org.bar;version="[1,1]"</pre></div><p>
seeks to import a package <code class="literal">org.foo</code> in the range <code class="literal">[2.0.0,3.0.0)</code> and a package
<code class="literal">org.bar</code> with the (exact) version <code class="literal">1.0.0</code>.
</p><p>If a version range is not specified on an import, the range <code class="literal">0</code> is assumed, meaning that
any version of this package would satisfy the import.</p></div><div class="section" title="Bundle Manifest Version"><div class="titlepage"><div><div><h4 class="title"><a name="N102AF"></a>Bundle Manifest Version</h4></div></div></div><p>Bundle manifests have a version which is <code class="literal">1</code> by default,
indicating OSGi Release 3 semantics.
Virgo is based on OSGi Release 4 and therefore expects bundle manifests to be
at version <code class="literal">2</code>, indicating OSGi Release 4 semantics.
The bundle manifest&rsquo;s version should be specified on the Bundle-ManifestVersion manifest header, exactly as follows:
</p><div class="informalexample"><pre class="programlisting">Bundle-ManifestVersion: 2
</pre></div><p>
</p></div><div class="section" title="Manifest Version"><div class="titlepage"><div><div><h4 class="title"><a name="N102C2"></a>Manifest Version</h4></div></div></div><p>Manifests themselves also have a version which <span class="emphasis"><em>must</em></span> be specified as <code class="literal">1.0</code>.
This is not an OSGi definition but part of the
(<a class="ulink" href="http://java.sun.com/javase/6/docs/technotes/guides/jar/jar.html" target="_top">JAR file specification</a>).
</p><div class="informalexample"><pre class="programlisting">Manifest-Version: 1.0
</pre></div><p>
</p></div></div></div><div class="navfooter"><hr><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></body></html>