blob: 843f4ca1a3174d504dc0e268205f1b3e6dd08a71 [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Chapter&nbsp;7.&nbsp;Bundles and Application Contexts</title><link rel="stylesheet" href="css/html.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.72.0"><link rel="start" href="index.html" title="Eclipse Gemini Blueprint Reference Guide"><link rel="up" href="reference.html" title="Part&nbsp;II.&nbsp;Reference Documentation"><link rel="prev" href="blueprint.html" title="Chapter&nbsp;6.&nbsp;OSGi 4.2 Blueprint Container"><link rel="next" href="app-deploy.html" title="Chapter&nbsp;8.&nbsp;Packaging and Deploying Spring-based OSGi applications"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="bnd-app-ctx"></a>Chapter&nbsp;7.&nbsp;Bundles and Application Contexts</h2></div></div></div><p>The unit of deployment (and modularity) in OSGi is the <span class="emphasis"><em>bundle</em></span> (see
section 3.2 of the OSGi Service Platform Core Specification). A bundle
known to the OSGi runtime is in one of three steady states: installed,
resolved, or active. Bundles may export services (objects) to the OSGi
service registry, and by so doing make these services available for other
bundles to discover and to use. Bundles may also export Java packages,
enabling other bundles to import the exported types.</p><p>In Spring the primary unit of modularity is an <span class="emphasis"><em>application context</em></span>,
which contains some number of beans (objects managed by the Spring
application context). Application contexts can be configured in a
hierarchy such that a child application context can see beans defined in a
parent, but not vice-versa. The Spring concepts of exporters and factory
beans are used to export references to beans to clients outside of the
application context, and to inject references to services that are defined
outside of the application context.</p><p>There is a natural affinity between an OSGi bundle and a Spring
application context. Using Gemini Blueprint, an active bundle may
contain a Spring application context, responsible for the instantiation,
configuration, assembly, and decoration of the objects (beans) within the
bundle. Some of these beans may optionally be exported as OSGi services
and thus made available to other bundles; beans within the bundle may also
be transparently injected with references to OSGi services.</p><p>This chapter describes the lifecycle relationship between bundles and their
application contexts, as imposed by Gemini Blueprint based on the events occurring at runtime,
inside an OSGi environment.</p><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="bnd-app-ctx:extender"></a>7.1.&nbsp;The Gemini Blueprint Extender Bundle</h2></div></div></div><div class="sidebar"><a name="extender-pattern"></a><p class="title"><b>Extender Pattern</b></p><p>A common pattern in OSGi applications is the <span class="emphasis"><em>extender</em></span>, that
(quoting <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.aqute.biz/Blog/HomePage" target="_top">Peter Kriens</a>,
OSGi Technical Director), &#8220;<span class="quote">allows other bundles to extend the functionality in a specific domain</span>&#8221;.
See <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.osgi.org/blog/2007/02/osgi-extender-model.html" target="_top">this</a> OSGi Alliance blog
entry for an in-depth explanation.
</p></div><p>The component responsible for detecting the <span class="emphasis"><em>Spring-powered bundles</em></span> and instantiating
their application context is the Gemini Blueprint <span class="emphasis"><em>extender</em></span>. It serves the same purpose as the <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://static.springframework.org/spring/docs/2.5.x/reference/webintegration.html" target="_top">ContextLoaderListener</a>
does for Spring web applications. Once the extender bundle is installed
and started it looks for any existing Spring-powered bundles that are
already in the <span class="emphasis"><em>ACTIVE</em></span> state and creates application contexts on their
behalf. In addition, it listens for bundle starting events and
automatically creates an application context for any Spring-powered
bundle that is subsequently started. <a href="app-deploy.html#app-deploy:headers" title="8.1.&nbsp;Bundle Format And Manifest Headers">Section&nbsp;8.1, &#8220;Bundle Format And Manifest Headers&#8221;</a>
describes what the extender recognizes as a "Spring-powered bundle" while
<a href="app-deploy.html#app-deploy:extender-configuration" title="8.3.&nbsp;Extender Configuration Options">Section&nbsp;8.3, &#8220;Extender Configuration Options&#8221;</a> how the extender can be configured.
The extender monitors the lifecycle of the bundle it manages and will destroy automatically the contexts for bundles
that are stopped. When the extender bundle itself is stopped, it will automatically close all the contexts that it manages,
based on the service dependency between them.
The extender bundle symbolic name is <code class="literal">org.eclipse.gemini.blueprint.extender</code>. </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="bnd-app-ctx:app-creation"></a>7.2.&nbsp;Application Context Creation</h2></div></div></div><p>Once started, the extender analyses the existing started bundles and monitors any new bundle that will start. Once a
Blueprint or Gemini Blueprint configuration is detected, the extender will create an application context for it in an asynchronous manner,
on a different thread then the one starting the bundle (or delivering the STARTED event).
This behaviour follows the OSGi specification recommendation and ensures that starting an OSGi Service Platform is fast and that
bundles with service inter-dependencies do not cause deadlock (waiting for each other) on startup, as pictured below: </p><div class="mediaobject" align="center"><img src="images/start-diagram.png" align="middle" alt="Application Context Sequence Diagram"></div><p>The extender considers only bundles successfully started, that is, bundles in
<span class="emphasis"><em>ACTIVE</em></span> state; bundles in other states are ignored.
Therefore a Spring-powered/Blueprint bundle will have its application context created <span class="emphasis"><em>after</em></span>
it has been fully started. It is possible to force synchronous/serialized creation of application contexts
for started bundles, on a bundle-by-bundle basis. See <a href="app-deploy.html#app-deploy:headers" title="8.1.&nbsp;Bundle Format And Manifest Headers">Section&nbsp;8.1, &#8220;Bundle Format And Manifest Headers&#8221;</a> for information
on how to specify this behaviour.</p><p>If application context creation fails for any reason then the
failure cause is logged. The bundle remains in the ACTIVE state; the application context lifecycle will not influence
the bundle lifecycle in anyway. Naturally, since the context has failed, so will the functionality associated with it;
for example there will be no services exported to the registry from the application context in this scenario.</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="bnd-app-ctx:app-creation:mandatory-deps"></a>7.2.1.&nbsp;Mandatory Service Dependencies</h3></div></div></div><p>If an application context declares mandatory availability for certain
imported OSGi services, the creation of the application context is blocked
until all the mandatory dependencies can be satisfied through matching services
available in the OSGi service registry. In practice, for most enterprise applications
built using Gemini Blueprint services, the set of available
services and bundles will reach a steady state once the platform and
its installed bundles are all started. In such a world, the behaviour of
waiting for mandatory dependencies simply ensures that bundles A and
B, where bundle A depends on services exported by bundle B, may be
started in any order.</p><p>A timeout applies to the wait for mandatory dependencies to be
satisfied. By default the timeout is set to 5 minutes, but this value
can be configured using the <code class="literal">timeout</code> directive. See
<a href="app-deploy.html#app-deploy:headers" title="8.1.&nbsp;Bundle Format And Manifest Headers">Section&nbsp;8.1, &#8220;Bundle Format And Manifest Headers&#8221;</a> for details.</p><p>Blueprint users could achieve the same result through the <code class="literal">blueprint.timeout</code>
attribute declared on the <code class="literal">Bundle-SymbolicName</code></p><p>It is possible to change the application context creation
semantics so that application context creation fails if all mandatory
services are not immediately available upon startup (see the aforementioned
section for more information).
Again, note that regardless of the configuration chosen, the failure of the
application context will not change the bundle state.</p><p>For more information on the <span class="emphasis"><em>availability</em></span> of imported services,
see <a href="service-registry.html#service-registry:refs:availability" title="9.2.1.&nbsp;Imported Service Availability">Section&nbsp;9.2.1, &#8220;Imported Service Availability&#8221;</a></p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="bnd-app-ctx:app-creation:app-ctx-publication"></a>7.2.2.&nbsp;Application Context Service Publication</h3></div></div></div><p>Once the application context creation for a bundle has
completed, the application context object is automatically exported as
a service available through the OSGi Service Registry. The context is
published under the interface
<code class="interfacename">org.springframework.context.ApplicationContext</code> (and
also all of the visible super-interfaces and types implemented by the
context). The published service has a service property named
<code class="literal">org.springframework.context.service.name</code> whose
value is set to the bundle symbolic name of the bundle hosting the
application context. In case of a Blueprint bundle, the container will be published
under <code class="interfacename">org.osgi.service.blueprint.container.BlueprintContainer</code>
while the bundle symbolic name will be published under <code class="literal">osgi.blueprint.container.symbolicname</code>
property.
</p><p>It is possible to prevent publication of the
application context as a service using a directive in the bundle's
manifest. See <a href="app-deploy.html#app-deploy:headers" title="8.1.&nbsp;Bundle Format And Manifest Headers">Section&nbsp;8.1, &#8220;Bundle Format And Manifest Headers&#8221;</a> for details.</p><p>Note: the application context is published as a service
primarily to facilitate testing, administration, and management.
Accessing this context object at runtime and invoking
<code class="literal">getBean()</code> or similar operations is discouraged. The
preferred way to access a bean defined in another application context
is to export that bean as an OSGi service from the defining context,
and then to import a reference to that service in the context that
needs access to the service. Going via the service registry in this
way ensures that a bean only sees services with compatible versions of
service types, and that OSGi platform dynamics are respected.</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="bnd-app-ctx:bnd-lifecycle"></a>7.3.&nbsp;Bundle Lifecycle</h2></div></div></div><p>OSGi is a dynamic platform: bundles may be installed, started,
updated, stopped, and uninstalled at any time during the running of the
framework.</p><p>When an active bundle is stopped, any services it exported during
its lifetime are automatically unregistered and the bundle returns to
the resolved state. A stopped bundle should release any resources it has
acquired and terminate any threads. Packages exported by a stopped
bundle continue to be available to other bundles.</p><p>A bundle in the resolved state may be uninstalled: packages that
were exported by an uninstalled bundle continue to be available to
bundles that imported them (but not to newly installed bundles).A bundle
in the resolved state may also be updated. The update
process migrates from one version of a bundle to another version of the
same bundle.</p><p>Finally of course, a resolved bundle can be started, which
transitions it to the active state.</p><p>The diagram below represents the bundle states and its transitions:</p><div class="mediaobject" align="center"><img src="images/bundle-states.png" align="middle" alt="Bundle States"></div><p>The OSGi <code class="literal">PackageAdmin</code>
<code class="literal">refreshPackages</code> operation refreshes packages across
the whole OSGi framework or a given subset of installed bundles. During
the refresh, an application context in an affected bundle will be
stopped and restarted. After a <code class="literal">refreshPackages</code>
operation, packages exported by older versions of updated bundles, or
packages exported by uninstalled bundles, are no longer available.
Consult the OSGi specifications for full details.</p><p>When a Spring-powered or Blueprint bundle is stopped, the application context
created for it is automatically destroyed. All services exported by the
bundle will be unregistered (removed from the service registry) and the
normal application context tear-down life-cycle is observed
(<code class="interfacename">org.springframework.beans.factory.DisposableBean</code> implementors
and <code class="literal">destroy-method</code>
callbacks are invoked on beans in the context).</p><p>If a Spring-powered bundle that has been stopped is subsequently
re-started, a new application context will be created for it.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="bnd-app-ctx:osgi-resource"></a>7.4.&nbsp;The Resource Abstraction</h2></div></div></div><p>The Spring Framework defines a resource abstraction for loading
resources within an application context (see <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://static.springframework.org/spring/docs/2.5.x/reference/resources.html" target="_top">Spring's
resource abstraction</a>). All resource loading is done through the
<code class="interfacename">org.springframework.core.io.ResourceLoader</code> associated with the application
context. The <code class="interfacename">org.springframework.core.io.ResourceLoader</code> is also
available to beans wishing to load resources programmatically. Resource paths with
explicit prefixes - such as <code class="literal">classpath:</code> - are treated uniformly
across all application context types (for example, web application
contexts and classpath-based application contexts). Relative resource
paths are interpreted differently based on the type of application
context being created. This enables easy integration testing outside
the ultimate deployment environment.</p><p>OSGi 4.0.x specification defines three different spaces from which a
resource can be loaded. Gemini Blueprint supports all of them through its dedicated OSGi-specific
application context and dedicated prefixes:</p><div class="table"><a name="osgi-search-strategies"></a><p class="title"><b>Table&nbsp;7.1.&nbsp;OSGi resource search strategies</b></p><div class="table-contents"><table summary="OSGi resource search strategies" width="100%" border="1"><colgroup><col><col><col></colgroup><thead><tr><th>OSGi Search Strategy</th><th>Prefix</th><th>Explanation</th></tr></thead><tbody><tr><td>Class Space</td><td><code class="literal">classpath:</code></td><td>Searches the bundle classloader (the bundle, all imported packages and required bundles). Forces the bundle to be resolved.
This method has similar semantics to
<a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www2.osgi.org/javadoc/r4/org/osgi/framework/Bundle.html#getResource(java.lang.String)" target="_top"><code class="literal">Bundle#getResource(String)</code></a></td></tr><tr><td>Class Space</td><td><code class="literal">classpath*:</code></td><td>Searches the bundle classloader (the bundle and all imported packages and required bundles). Forces the bundle to be resolved.
This method has similar semantics to
<a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www2.osgi.org/javadoc/r4/org/osgi/framework/Bundle.html#getResources(java.lang.String)" target="_top"><code class="literal">Bundle#getResources(String)</code></a>
</td></tr><tr><td>JAR File (or JarSpace)</td><td><code class="literal">osgibundlejar:</code></td><td>Searches only the bundle jar. Provides low-level access without requiring the bundle to be resolved.</td></tr><tr><td>Bundle Space</td><td><code class="literal">osgibundle:</code></td><td>Searches the bundle jar and its attached fragments (if there are any). Does not create a class loader or force the bundle to be resolved.</td></tr></tbody></table></div></div><br class="table-break"><p>Please consult section 4.3.12 of the OSGi specification for an in depth explanation of the differences between them.
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/admons/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top">If no prefix is specified, the bundle space (<code class="literal">osgibundle:</code>) will be used.</td></tr></table></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/admons/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top">Due to the OSGi dynamic nature, a bundle classpath can change during its life time (for example when dynamic imports are used). This might cause different
classpath <code class="interfacename">Resource</code>s to be returned when doing pattern matching based on the running environment or target platform.</td></tr></table></div><p>All of the regular Spring resource prefixes such as <code class="literal">file:</code> and
<code class="literal">http:</code> are also supported, as are the pattern matching wildcards.
Resources loaded using such prefixes may come from any location, they
are not restricted to being defined within the resource-loading bundle
or its attached fragments.</p><p>OSGi platforms may define their own unique prefixes for accessing
bundle contents. For example, Equinox defines the <code class="literal">bundleresource:</code> and
<code class="literal">bundlentry:</code> prefixes. These platform specific prefixes may also be
used with Gemini Blueprint, at the cost, of course, of tying yourself to a
particular OSGi implementation.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="bnd-app-ctx:bundle-scope"></a>7.5.&nbsp;Bundle Scope</h2></div></div></div><p>Gemini Blueprint introduces a new bean scope named <code class="literal">bundle</code>. This scope is relevant for
beans exported as an OSGi service and can be described as <span class="emphasis"><em>one instance per bundle</em></span>.
Beans exported as OSGi service, that have <code class="literal">bundle</code> scope, will result in a different instance created for
each unique bundle that imports the service through the OSGi service registry. Consumers of the same bundle (whether defined
through Gemini Blueprint or not) will see the same bean instance. When a bundle has stopped importing the bundle (for whatever reason),
the bean instance is disposed.
To the declaring bundle, a <code class="literal">bundle</code>-scoped bean behaves just like a singleton (i.e. there is only
one instance per bundle, including the declaring one).This contract lifecycle is similar to that of the
<code class="interfacename">org.osgi.framework.ServiceFactory</code> interface.</p><p>For more information regarding service publication and consumption, see <a href="service-registry.html" title="Chapter&nbsp;9.&nbsp;The Service Registry">Chapter&nbsp;9, <i xmlns:xlink="http://www.w3.org/1999/xlink">The Service Registry</i></a>.</p><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/admons/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top">The bundle scope is relevant, only if the declaring bean is consumed through the OSGi service registry. That is,
instances are created and destroyed (tracked) only when the bean exported as a service, is requested or released as an OSGi service
by other bundles.</td></tr></table></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="bnd-app-ctx:access-bnd-ctx"></a>7.6.&nbsp;Accessing the BundleContext</h2></div></div></div><p>In general there is no need to depend on any OSGi APIs when using
the Gemini Blueprint support. If you <span class="emphasis"><em>do</em></span> need
access to the OSGi <code class="interfacename">BundleContext</code> object for your
bundle, then Spring makes this easy to do.</p><p>The OSGi application context created by the Spring extender will
automatically contain a bean of type <code class="interfacename">BundleContext</code>
and with name <code class="literal">bundleContext</code>. You can inject a
reference to this bean into any bean in the application context either
by-name or by-type. In addition, Gemini Blueprint defines the
interface
<code class="interfacename">org.eclipse.gemini.blueprint.context.BundleContextAware</code>:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> BundleContextAware {
<span class="hl-keyword">public</span> <span class="hl-keyword">void</span> setBundleContext(BundleContext context);
}</pre><p>Any bean implementing this interface will be injected with a
reference to the bundle context when it is configured by Spring. If you
wish to use this facility within a bundle, remember to import the
package <code class="literal">org.eclipse.gemini.blueprint.context</code> in your
bundle manifest since otherwise the interface will not be visible to your bundle.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="bnd-app-ctx:app-destruction"></a>7.7.&nbsp;Application Context Destruction</h2></div></div></div><p>The application context is bound to the bundle in which it lives. Thus, if the declaring
bundle is being shutdown (for whatever reasons), the application context will be destroyed as well,
all exported services being unregistered and all service imported dispose of.
</p><p>As opposed to the application creation, the application context is destroyed in a synchronized manner,
on the same thread that stops the bundle. This is required since once stopped, a bundle can not longer be used
(even for class loading) preventing the application context shutdown from executing correctly.
</p><div class="mediaobject" align="center"><img src="images/stop-diagram.png" align="middle" alt="Application Context Sequence Diagram"></div><p>Note that a bundle can be closed individually or as part of a bigger
event such as shutting down the entire OSGi platform. In this case or when the extender
bundle is being closed down, the application contexts will be closed in a managed
manner, based on the service dependencies between them. Please see the next section for more
details.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="bnd-app-ctx:access-bnd-ctx:stop-extender"></a>7.8.&nbsp;Stopping the Extender Bundle</h2></div></div></div><div class="sidebar"><a name="shutdown-2.x"></a><p class="title"><b>Shutdown algorithm change in 2.x</b></p><p>The shutdown algorithm implementation in Gemini Blueprint 1.0 has been revised to be better
aligned with the Blueprint Container spec. Namely, the previous implementation performed ordering
in only one pass while the latter performs multiple steps to accommodate the service changes in
the OSGi space. Users should not discover any differences at runtime however, if that's not the case,
please let us know.
</p></div><p>If the extender bundle is stopped, then all the application
contexts created by the extender will be destroyed. The algorithm described here is identical
to that used by the Blueprint specification (section 121.3.11). Application contexts
are shutdown in the following order:</p><div class="orderedlist"><ol type="1"><li><p><a name="bnd-app-ctx:access-bnd-ctx:stop-extender:shutdown.step.1"></a>Application contexts that do not export any services, or that
export services that are not currently referenced, are shutdown in
reverse order of bundle id. (Most recently installed bundles have
their application contexts shutdown first).</p></li><li><p>Shutting down the application contexts in step 1 may have
released references these contexts were holding such that there are
now additional application contexts that can be shutdown. If so,
repeat <a href="bnd-app-ctx.html#bnd-app-ctx:access-bnd-ctx:stop-extender:shutdown.step.1">step 1</a> again.</p></li><li><p>If there are no more active application contexts, we have
finished. If there <span class="emphasis"><em>are</em></span> active application
contexts then there must be a cyclic dependency of references. The
circle is broken by determining the highest ranking service exported
by each context: the bundle with the lowest ranking service in this
set (or in the event of a tie, the highest service id), is shut
down. Repeat from <a href="bnd-app-ctx.html#bnd-app-ctx:access-bnd-ctx:stop-extender:shutdown.step.1">step 1</a>.</p></li></ol></div></div></div><div xmlns:fo="http://www.w3.org/1999/XSL/Format" class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="blueprint.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="app-deploy.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter&nbsp;6.&nbsp;OSGi 4.2 Blueprint Container&nbsp;</td><td width="20%" align="center"><span style="color:white;font-size:90%;"><a href="http://www.SpringSource.com/" title="SpringSource - Spring from the Source">Sponsored by SpringSource
</a></span></td><td width="40%" align="right" valign="top">&nbsp;Chapter&nbsp;8.&nbsp;Packaging and Deploying Spring-based OSGi applications</td></tr></table></div></body></html>