felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Felix > Composite Bundles
Date Wed, 30 Jun 2010 14:54:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1810/9/1/_/styles/combined.css?spaceKey=FELIX&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/FELIX/Composite+Bundles">Composite
Bundles</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~heavy@ungoverned.org">Richard
S. Hall</a>
    </h4>
        <br/>
                         <h4>Changes (17)</h4>
                                 
    
<div id="page-diffs">
            <table class="diff" cellpadding="0" cellspacing="0">
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >h1. Technical approach <br>
<br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">The
overall technical approach is to build a layer on top of the virtual bundle concept (proposed
separately) to manage composite as a layer above the framework. The specific approach is to
forgo an API-based approach to support a simple, declarative approach. Therefore, the technical
approach is actually divided into two halves: composite declaration and composite lifecycle
management. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">The
overall technical approach is to build a layer on top of the virtual bundle concept (proposed
separately) to manage composites as a layer above the framework. The specific approach is
to forgo an API-based approach to support a simple, declarative approach. The technical approach
is divided into two halves for supporting a more simplistic composite model and extending
this model to support additional scenarios at the expense of making it more complicated. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">NOTE:
The goal is not to completely rule out any API, but to keep things simple until some real-world
experience is gained at which point API could potentially be introduced. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h2.
Simple composite model <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">2</span><span
class="diff-added-chars"style="background-color: #dfd;">3</span>.</span> Composite
declaration <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">NOTE:
The goal is not to completely rule out any API, but to keep things simple until some real-world
experience is gained at which point API could potentially be introduced. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >A composite bundle is declared using
a set of manifest-like headers, which is familiar to bundle developers and fits well with
the virtual bundle proposal, where virtual bundles are installed with a given set of headers.
Many existing headers are reused to declare a composite bundle, but not all are applicable
(e.g., {{Bundle-ClassPath}}, {{Bundle-Activator}}, {{Bundle-NativeCode}}, {{Bundle-ActivationPolicy}}).
Other than explicitly disallowed headers, all other headers maintain their normal meaning.
For example, code dependencies are handled by: <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >This composite contains five bundles
and exports {{org.foo.shape}} from the bundle with the symbolic name {{org.foo.shape}}. Further,
it also imports the log service package and any services implementing the {{org.foo.shape.SimpleShape}}
interface from the package it exports. <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">This
proposal introduces one final header, which is: <br> <br>* {{Provide-Bundle}}
- a comma-delimited set of symbolic names specifying the constituent bundles provided by the
composite bundle to the parent framework. <br> <br>The provided bundles will be
manifested in the parent framework as virtual bundles themselves. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >These declarative headers define the
entire capabilities of a composite bundle. To summarize, these capabilities are: containing
bundles, importing/exporting packages, requiring/providing bundles, and importing/exporting
services. <br> <br>NOTE: It is not clear if {{Import-Package}} should essentially
support an &quot;export as&quot; directive where the composite creator explicitly
specifies how the imported package gets converted to an export internally or if this should
be somehow automatically derived from the actual injected wire. If the latter, then this relates
to the rich wiring section in the open issues.  <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">2</span><span
class="diff-added-chars"style="background-color: #dfd;">3</span>.</span> Composite
lifecycle management <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Since composite bundles
are implemented as virtual bundles, access to their content and portions of their lifecycle
are controlled by an external manager. As a result, their lifecycle handling is slightly different
from normal bundles. This section describes various composite lifecycle management issues.
<br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">3</span><span
class="diff-added-chars"style="background-color: #dfd;">4</span>.</span> Composite
manager <br></td></tr>
            <tr><td class="diff-unchanged" > <br>The composite manager results
from the use of virtual bundles. The composite manager is largely responsible for actually
realizing the capabilities embodied in the composite declaration headers. This means it is
the composite manager&#39;s responsibility to: <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >The precise approach the composite
manager uses to accomplish these responsibilities is not specified. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">3</span><span
class="diff-added-chars"style="background-color: #dfd;">4</span>.</span> Installing
composites <br></td></tr>
            <tr><td class="diff-unchanged" > <br>If an &quot;install
hook&quot; is introduced in the virtual bundle proposal, then the composite manager can
use it to seamlessly install composite bundles via the {{BundleContext.installBundle()}} method,
like any normal bundle. If install hooks are not proposed, then it could provide a simple
service for installing composites. A composite is installed with a complete composite description,
which forms the manifest of the installed virtual bundle. As such, composite installation
is effectively atomic. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">3</span><span
class="diff-added-chars"style="background-color: #dfd;">4</span>.</span> Resolving
composites <br></td></tr>
            <tr><td class="diff-unchanged" > <br>The composite&#39;s
wires for its required packages and bundles are injected into the composite&#39;s virtual
module by the framework, like for all virtual bundles, which the composite manager can use
for delegation purposes for the constituent bundles. If a composite is resolved, then it is
possible to load classes from it. After a composite is resolved it is also possible to realize
any provided bundles in the parent framework. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">3</span><span
class="diff-added-chars"style="background-color: #dfd;">4</span>.</span> Starting
and stopping composites <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Starting a composite bundle
starts all internal constituent bundles. Likewise, stopping a composite bundle stops all constituent
bundles. Composite bundles do not have user-defined activators, although the composite manager
may make use of an activator. For active composites, the composite manager must provide constituent
bundles access to imported services and must make exported services available in the parent
framework. Conversely, when a composite bundle is no longer active, it must stop providing
access to services. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >After a composite bundle is stopped,
it should remain resolved and continue to provide access to its exported packages and provided
bundles. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">3</span><span
class="diff-added-chars"style="background-color: #dfd;">4</span>.</span> Refreshing
a composite <br></td></tr>
            <tr><td class="diff-unchanged" > <br>When refreshing a composite,
all constituent bundles are refreshed and the composite bundle returns to the installed state.
Any provided bundles in the parent framework will also be refreshed and returned to the installed
state and will not be resolvable until the composite is resolved. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >NOTE 2: Refreshing a provided bundle
should likely be a no-op internal to the composite bundle, although it will cause a refresh
of dependent bundles in the parent framework. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">3</span><span
class="diff-added-chars"style="background-color: #dfd;">4</span>.</span> Uninstalling
a composite <br></td></tr>
            <tr><td class="diff-unchanged" > <br>The normal bundle uninstall
operation does not directly mean that a bundle is no longer in use, since it is still possible
to load classes from it. Further, the framework provides to additional callbacks or state
changes to notify when it is really done with a bundle. As a result, if a composite is uninstalled,
the composite manager must immediately refresh it to perform proper clean up. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >NOTE: This could be improved with
a {{VirtualModule.dispose()}} method, indicating that the framework is really done with the
virtual module. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">3</span><span
class="diff-added-chars"style="background-color: #dfd;">4</span>.</span> Relationship
to composite manager lifecycle <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Since the composite manager
manages all aspects of the composite&#39;s content, its active lifetime scopes its managed
composites. In other words, if the composite manager is stopped, then it explicitly causes
all of its managed composites to refresh and return to the installed state. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">3</span><span
class="diff-added-chars"style="background-color: #dfd;">4</span>.</span> Lifecycle
flow <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Lifecycle control flows
down, not up <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h2.
Extended composite model <br> <br>h3. Extended declaration <br> <br>This
proposal introduces one final header, which is: <br> <br>* {{Provide-Bundle}}
- a comma-delimited set of symbolic names specifying the constituent bundles provided by the
composite bundle to the parent framework. <br> <br>The provided bundles will be
manifested in the parent framework as virtual bundles themselves. <br> <br>h3.
Extended lifecycle <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h1. Open issues <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
        </table>
</div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h1><a name="CompositeBundles-Overview"></a>Overview</h1>

<p>The OSGi framework supports deploying bundles into a flat and basically globally
bundle space. The idea behind this approach can be summarized as, "the deployed set of bundles
is your application configuration." This approach has performed well over the years; however,
as OSGi technology is used in more and more complicated scenarios, this approach is not always
sufficient. For example, when trying to run multiple applications in a single framework instance
or when applications become so large that sets of bundles start mapping onto logical subsystems.
In these types of situations, it is possible for the configurations of different applications
or subsystems to interfere with each other.</p>

<p>To address some of these issues, this proposal introduces a composite bundle concept
built on top of virtual bundles. The main goal of this proposal is to provide an isolation
mechanism for groups of bundles, while still allowing collaboration among those groups and
to manage everything as a layer above the framework.</p>

<h1><a name="CompositeBundles-Usecases"></a>Use cases</h1>

<p>Some potential use cases for composite bundles:</p>

<ul>
	<li>Large application subsystems can be modeled as a composite bundle.</li>
	<li>Different applications running in the same framework instance can be isolated from
each other inside of composite bundles.</li>
	<li>Web servers could model EARs and composite bundles.</li>
	<li>Groups of bundles needing lifecycle management as a whole can be modeled as a composite
bundle.</li>
</ul>


<p>This list is not intended to be exhaustive.</p>

<h1><a name="CompositeBundles-Terminology"></a>Terminology</h1>

<p>The following terms are used in this document:</p>

<ul>
	<li>Composite bundle - a bundle whose contents is actually a set of bundles that appear
to be running inside of another framework instance.</li>
	<li>Parent framework - the framework in which a composite bundle is installed.</li>
	<li>Composite framework - the framework running inside the composite bundle (this term
may not be necessary).</li>
</ul>


<h1><a name="CompositeBundles-Technicalapproach"></a>Technical approach</h1>

<p>The overall technical approach is to build a layer on top of the virtual bundle concept
(proposed separately) to manage composites as a layer above the framework. The specific approach
is to forgo an API-based approach to support a simple, declarative approach. The technical
approach is divided into two halves for supporting a more simplistic composite model and extending
this model to support additional scenarios at the expense of making it more complicated.</p>

<h2><a name="CompositeBundles-Simplecompositemodel"></a>Simple composite
model</h2>

<h3><a name="CompositeBundles-Compositedeclaration"></a>Composite declaration</h3>

<p>NOTE: The goal is not to completely rule out any API, but to keep things simple until
some real-world experience is gained at which point API could potentially be introduced.</p>

<p>A composite bundle is declared using a set of manifest-like headers, which is familiar
to bundle developers and fits well with the virtual bundle proposal, where virtual bundles
are installed with a given set of headers. Many existing headers are reused to declare a composite
bundle, but not all are applicable (e.g., <tt>Bundle-ClassPath</tt>, <tt>Bundle-Activator</tt>,
<tt>Bundle-NativeCode</tt>, <tt>Bundle-ActivationPolicy</tt>). Other
than explicitly disallowed headers, all other headers maintain their normal meaning. For example,
code dependencies are handled by:</p>

<ul>
	<li><tt>Import-Package</tt> - the packages imported by the composite bundle
from the parent framework.</li>
	<li><tt>Require-Bundle</tt> - the bundles required by the composite bundle
from the parent framework.</li>
	<li><tt>Export-Package</tt> - the packages exported by the composite bundle
to the parent framework.</li>
</ul>


<p>For service dependencies, this proposal resurrects the following headers:</p>

<ul>
	<li><tt>Import-Service</tt> - the services imported by the composite bundle
(exact syntax is yet to be defined, but a list of filters is a reasonable starting point).</li>
	<li><tt>Export-Service</tt> - the services exported by the composite bundle
(exact syntax is yet to be defined, but a list of filters is a reasonable starting point).</li>
</ul>


<p>A new header is introduced to declare the composite's constituent bundles:</p>

<ul>
	<li><tt>Include-Bundle</tt> - A comma-separate list of bundle URLs.</li>
</ul>


<p>To simplify matching a composite's exported packages to its contained bundles, this
proposal introduces a new <tt>from</tt> directive for <tt>Export-Package</tt>,
which is used to specify the symbolic name of the providing bundle. Consider the following
composite declaration:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>Bundle-ManifestVersion: 2
Bundle-Name: Paint Program
Bundle-SymbolicName: org.foo.paint.composite
Include-Bundle: \
 file:/Users/rickhall/Projects/book-trunk/code/chapter04/paint-example/bundles/shape-4.0.jar,
\
 file:/Users/rickhall/Projects/book-trunk/code/chapter04/paint-example/bundles/paint-4.0.jar,
\
 file:/Users/rickhall/Projects/book-trunk/code/chapter04/paint-example/bundles/circle-4.0.jar,
\
 file:/Users/rickhall/Projects/book-trunk/code/chapter04/paint-example/bundles/square-4.0.jar,
\
 file:/Users/rickhall/Projects/book-trunk/code/chapter04/paint-example/bundles/triangle-4.0.jar
Export-Package: org.foo.shape; from:=org.foo.shape; version="4.0"
Import-Package: org.osgi.service.log; version=1.0.0
Import-Service: org.foo.shape.SimpleShape
</pre>
</div></div>

<p>This composite contains five bundles and exports <tt>org.foo.shape</tt>
from the bundle with the symbolic name <tt>org.foo.shape</tt>. Further, it also
imports the log service package and any services implementing the <tt>org.foo.shape.SimpleShape</tt>
interface from the package it exports.</p>

<p>These declarative headers define the entire capabilities of a composite bundle. To
summarize, these capabilities are: containing bundles, importing/exporting packages, requiring/providing
bundles, and importing/exporting services.</p>

<p>NOTE: It is not clear if <tt>Import-Package</tt> should essentially support
an "export as" directive where the composite creator explicitly specifies how the imported
package gets converted to an export internally or if this should be somehow automatically
derived from the actual injected wire. If the latter, then this relates to the rich wiring
section in the open issues. </p>

<h3><a name="CompositeBundles-Compositelifecyclemanagement"></a>Composite
lifecycle management</h3>

<p>Since composite bundles are implemented as virtual bundles, access to their content
and portions of their lifecycle are controlled by an external manager. As a result, their
lifecycle handling is slightly different from normal bundles. This section describes various
composite lifecycle management issues.</p>

<h4><a name="CompositeBundles-Compositemanager"></a>Composite manager</h4>

<p>The composite manager results from the use of virtual bundles. The composite manager
is largely responsible for actually realizing the capabilities embodied in the composite declaration
headers. This means it is the composite manager's responsibility to:</p>

<ul>
	<li>Manage a composite bundle's constituent bundles.</li>
	<li>Provide constituent bundles access to imported packages, required bundles, and
imported services.</li>
	<li>Provide the parent framework access to exported packages, provided bundles, and
exported services.</li>
	<li>Manage the overall lifecycle of composite bundles.</li>
</ul>


<p>The precise approach the composite manager uses to accomplish these responsibilities
is not specified.</p>

<h4><a name="CompositeBundles-Installingcomposites"></a>Installing composites</h4>

<p>If an "install hook" is introduced in the virtual bundle proposal, then the composite
manager can use it to seamlessly install composite bundles via the <tt>BundleContext.installBundle()</tt>
method, like any normal bundle. If install hooks are not proposed, then it could provide a
simple service for installing composites. A composite is installed with a complete composite
description, which forms the manifest of the installed virtual bundle. As such, composite
installation is effectively atomic.</p>

<h4><a name="CompositeBundles-Resolvingcomposites"></a>Resolving composites</h4>

<p>The composite's wires for its required packages and bundles are injected into the
composite's virtual module by the framework, like for all virtual bundles, which the composite
manager can use for delegation purposes for the constituent bundles. If a composite is resolved,
then it is possible to load classes from it. After a composite is resolved it is also possible
to realize any provided bundles in the parent framework.</p>

<h4><a name="CompositeBundles-Startingandstoppingcomposites"></a>Starting
and stopping composites</h4>

<p>Starting a composite bundle starts all internal constituent bundles. Likewise, stopping
a composite bundle stops all constituent bundles. Composite bundles do not have user-defined
activators, although the composite manager may make use of an activator. For active composites,
the composite manager must provide constituent bundles access to imported services and must
make exported services available in the parent framework. Conversely, when a composite bundle
is no longer active, it must stop providing access to services.</p>

<p>NOTE: For a provided bundle into the parent framework, it is not clear how we should
tie its lifecycle to the corresponding constituent bundle and/or whether it should be controllable
in the parent framework. For simplicity, it is probably better to effectively make it a no-op.</p>

<p>After a composite bundle is stopped, it should remain resolved and continue to provide
access to its exported packages and provided bundles.</p>

<h4><a name="CompositeBundles-Refreshingacomposite"></a>Refreshing a composite</h4>

<p>When refreshing a composite, all constituent bundles are refreshed and the composite
bundle returns to the installed state. Any provided bundles in the parent framework will also
be refreshed and returned to the installed state and will not be resolvable until the composite
is resolved.</p>

<p>NOTE 1: Another approach for provided bundles is to uninstall and refresh them.</p>

<p>NOTE 2: Refreshing a provided bundle should likely be a no-op internal to the composite
bundle, although it will cause a refresh of dependent bundles in the parent framework.</p>

<h4><a name="CompositeBundles-Uninstallingacomposite"></a>Uninstalling a
composite</h4>

<p>The normal bundle uninstall operation does not directly mean that a bundle is no
longer in use, since it is still possible to load classes from it. Further, the framework
provides to additional callbacks or state changes to notify when it is really done with a
bundle. As a result, if a composite is uninstalled, the composite manager must immediately
refresh it to perform proper clean up.</p>

<p>NOTE: This could be improved with a <tt>VirtualModule.dispose()</tt>
method, indicating that the framework is really done with the virtual module.</p>

<h4><a name="CompositeBundles-Relationshiptocompositemanagerlifecycle"></a>Relationship
to composite manager lifecycle</h4>

<p>Since the composite manager manages all aspects of the composite's content, its active
lifetime scopes its managed composites. In other words, if the composite manager is stopped,
then it explicitly causes all of its managed composites to refresh and return to the installed
state.</p>

<h4><a name="CompositeBundles-Lifecycleflow"></a>Lifecycle flow</h4>

<p>Lifecycle control flows down, not up</p>

<h2><a name="CompositeBundles-Extendedcompositemodel"></a>Extended composite
model</h2>

<h3><a name="CompositeBundles-Extendeddeclaration"></a>Extended declaration</h3>

<p>This proposal introduces one final header, which is:</p>

<ul>
	<li><tt>Provide-Bundle</tt> - a comma-delimited set of symbolic names specifying
the constituent bundles provided by the composite bundle to the parent framework.</li>
</ul>


<p>The provided bundles will be manifested in the parent framework as virtual bundles
themselves.</p>

<h3><a name="CompositeBundles-Extendedlifecycle"></a>Extended lifecycle</h3>

<h1><a name="CompositeBundles-Openissues"></a>Open issues</h1>

<h2><a name="CompositeBundles-Richwiringinformation"></a>Rich wiring information</h2>

<p>Currently, the wiring information provided by the virtual bundle proposal has been
kept purposely simplistic. To fully implement aspects of composites, like requiring/providing
bundles, it is necessary to get richer information from the wires, such as the type of capability.
Further, the wiring information needs to be at the module-level (i.e., bundle revision level),
not at the bundle level.</p>

<h1><a name="CompositeBundles-Consideredalternatives"></a>Considered alternatives</h1>

<p>TBD</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/FELIX/Composite+Bundles">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=23331295&revisedVersion=11&originalVersion=10">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/FELIX/Composite+Bundles?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message