blob: 6f0155987ada3302a8c8dd0957d526f8762eee05 [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>2.2&nbsp;OSGi Concepts</title><link rel="stylesheet" href="css/stylesheet.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"><link rel="home" href="index.html" title="Virgo User Guide"><link rel="up" href="ch02.html" title="2.&nbsp;Concepts"><link rel="prev" href="ch02.html" title="2.&nbsp;Concepts"><link rel="next" href="ch02s03.html" title="2.3&nbsp;Spring DM and Blueprint Concepts"><!--Begin Google Analytics code--><script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script><script type="text/javascript">
var pageTracker = _gat._getTracker("UA-2728886-3");
pageTracker._setDomainName("none");
pageTracker._setAllowLinker(true);
pageTracker._trackPageview();
</script><!--End Google Analytics code--></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">2.2&nbsp;OSGi Concepts</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch02.html">Prev</a>&nbsp;</td><th width="60%" align="center">2.&nbsp;Concepts</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="ch02s03.html">Next</a></td></tr></table><hr></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="concepts.osgi"></a>2.2&nbsp;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" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e161"></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 &#8220;<span class="quote">by name</span>&#8221; and &#8220;<span class="quote">by identifier</span>&#8221; (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 &#8220;<span class="quote">by identifier</span>&#8221; 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&#8217;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" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e246"></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 &#8220;<span class="quote">refresh packages</span>&#8221; 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="d0e281"></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" lang="en"><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>&#8230;implement the interface with a class <code class="literal">SomeImpl</code>:
</p><pre class="programlisting">package org.bar.impl;
class SomeImpl implements SomeInterface {
&#8230;
}
</pre><p>
</p><p>&#8230;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 &#8220;<span class="quote">refresh packages</span>&#8221; 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="2.3&nbsp;Spring DM and Blueprint Concepts">Spring DM concepts</a>.)</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e341"></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" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e346"></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 (&#8220;<span class="quote"><code class="literal">.</code></span>&#8221;) 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" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e404"></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
&#8220;<span class="quote"><code class="literal">[</code></span>&#8221; or &#8220;<span class="quote"><code class="literal">]</code></span>&#8221; denotes
an <span class="emphasis"><em>inclusive</em></span> end of the range and a round bracket
&#8220;<span class="quote"><code class="literal">(</code></span>&#8221; or &#8220;<span class="quote"><code class="literal">)</code></span>&#8221; 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 type="disc"><li><p>A &#8220;<span class="quote">strict</span>&#8221; version range, such as <code class="literal">[1.2,1.2]</code>, which
denotes that version and only that version.</p></li><li><p>A &#8220;<span class="quote">half-open</span>&#8221; 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><p>An &#8220;<span class="quote">unbounded</span>&#8221; 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" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e491"></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" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e523"></a>Bundle Version</h4></div></div></div><p>Each bundle has a version.
The bundle&#8217;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" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e539"></a>Package Version</h4></div></div></div><p>Each exported package has a version.
The exported package&#8217;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" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e598"></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&#8217;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" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e614"></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><!--Begin LoopFuse code--><script src="http://loopfuse.net/webrecorder/js/listen.js" type="text/javascript"></script><script type="text/javascript">
_lf_cid = "LF_48be82fa";
_lf_remora();
</script><!--End LoopFuse code--><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch02.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="ch02.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="ch02s03.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2.&nbsp;Concepts&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;2.3&nbsp;Spring DM and Blueprint Concepts</td></tr></table></div></body></html>