aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dav...@apache.org
Subject svn commit: r800363 - in /websites/production/aries: ./ content/modules/spi-fly.html
Date Fri, 16 Dec 2011 15:41:12 GMT
Author: davidb
Date: Fri Dec 16 15:41:12 2011
New Revision: 800363

Log:
Updated SPI Fly documentation.

Modified:
    websites/production/aries/   (props changed)
    websites/production/aries/content/modules/spi-fly.html

Propchange: websites/production/aries/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Dec 16 15:41:12 2011
@@ -1 +1 @@
-/websites/staging/aries/trunk:782169-800240
+/websites/staging/aries/trunk:782169-800362

Modified: websites/production/aries/content/modules/spi-fly.html
==============================================================================
--- websites/production/aries/content/modules/spi-fly.html (original)
+++ websites/production/aries/content/modules/spi-fly.html Fri Dec 16 15:41:12 2011
@@ -250,35 +250,73 @@
           </td>
           <td height="100%" width="100%">
             <!-- Content -->
-            <div class="wiki-content"><h1 id="spi-fly">SPI-Fly</h1>
+            <div class="wiki-content"><h1 id="spi_fly">SPI Fly</h1>
 <p>This page describes the SPI Fly component.
 The SPI Fly component is aimed at providing general support for the JRE SPI
-mechanism (including the usage of <tt>java.util.ServiceLoader</tt> and <tt>META-INF/services</tt>)
in OSGi.</p>
-<p>There are currently standardization efforts ongoing in the OSGi Alliance for which
the SPI-Fly project is a prototype. 
-For more information, see RFC 167 in the OSGi Enterprise 4.4 EA draft: <a href="http://www.osgi.org/download/osgi-early-draft-2011-05.pdf">http://www.osgi.org/download/osgi-early-draft-2011-05.pdf</a></p>
-<p>The code can be found in
-<a href="http://svn.apache.org/repos/asf/aries/trunk/spi-fly">http://svn.apache.org/repos/asf/aries/trunk/spi-fly</a>.</p>
-<p>Currently the implementation does the following:</p>
-<p>Providers:</p>
+mechanism, including the usage of <tt>java.util.ServiceLoader</tt>, 
+<tt>META-INF/services</tt> and similar methods in OSGi.</p>
+<h2 id="the_problem">The Problem</h2>
+<p><tt>java.util.ServiceLoader.load()</tt> and other similar methods such
as 
+<tt>sun.misc.Service.providers()</tt>, but also other static finder methods such
as the 
+<tt>FactoryFinder.find()</tt> methods try to locate 'service' implementations
by looking for 
+resources in the META-INF/services directory of all the jars visible to the 
+<strong><em>Thread Context ClassLoader</em></strong> (TCCL).</p>
+<p>There are a number of issues with this approach in OSGi:</p>
+<ol>
+<li>The Thread Context ClassLoader is not defined in general in an OSGi context. It
can and has to be set by the caller and OSGi cannot enforce that. </li>
+<li>A bundle can't Import-Package META-INF/services as potentially many bundles will
contain this pseudo-package and the OSGi framework will only bind a single exporter to an
importer for a given package.</li>
+<li>Instantiating an SPI provider generally requires access to internal implementation
classes, by exporting these classes an implementing bundle would break its encapsulation.
</li>
+<li>Even if an implementation class was exported, importing this class in a consumer
bundle would bind it to the specific implementation package provided, which violates the principle
of loose coupling.</li>
+<li>Bundles have a dynamic life-cycle which means that provided services could disappear
when a bundle is updated or uninstalled. The java.util.ServiceLoader API does not provide
a mechanism to inform service consumers of such an event.</li>
+</ol>
+<p>The SPI Fly project makes it possible to use existing code that uses 
+<tt>ServiceLoader.load()</tt> and similar mechanisms under OSGi.</p>
+<h2 id="making_it_work">Making it Work</h2>
+<p>In order to make the ServiceLoader approach work under OSGi, calling code can be
woven
+to set the TCCL to the appropriate providers very briefly, only for the duration of the
+call. The SPI Fly component does precisely this.</p>
+<h3 id="providers">Providers</h3>
+<p>First for all, SPI Fly needs to be made aware of any bundles that provide the services.
+These bundles are made visible through the TCCL for the duration of the <tt>ServiceLoader.load()</tt>
+(or similar) call.</p>
+<p>To mark a bundle as a Provider, set the <strong><tt>SPI-Provider</tt></strong>
manifest header:</p>
 <ul>
-<li>It only considers provider bundles that have the following Manifest (opt-in)
-header: <strong>SPI-Provider = </strong>*</li>
-<li>For every new bundle being installed that has the opt-in header, it
-checks the META-INF/services directory for any files. If found it registers
-a service in the Service Registry for each implementation found with the
-following property
- <em>spi.provider.url = <the URL to the associated META-INF/services file></em></li>
+<li><strong>SPI-Provider: </strong>* will consider all providers found
in the META-INF/services
+directory and register them.</li>
+<li><strong>SPI-Provider: org.acme.MySvc1, org.acme.MySvc2</strong> will
only consider MySvc1 and
+MySvc2.</li>
 </ul>
-<p>Consumers:</p>
+<p>Additionally services found in META-INF/services are registered in the OSGi Service

+Registry. Each service is registered with the <em>spi.provider.url</em> service
registration
+property.</p>
+<p>The <tt>SPI-Provider</tt> header can either be set in the providing
bundle itself or in a wrapper bundle
+that holds the original unmodified jar containing the provider internally as a 
+on the <tt>Bundle-ClassPath</tt>.</p>
+<h3 id="consumers">Consumers</h3>
+<p>Service consumers also need to opt-in to the process. </p>
+<p>To specify a consumer, add the <tt>SPI-Consumer</tt> manifest header
to the client bundle. This header 
+will opt-in the bundle to the weaving process where for the duration of the specified call
+the TCCL will be set to the matching provider bundle(s).</p>
 <ul>
-<li>It only considers consumer bundles that have the following Manifest (opt-in) header:
-<strong>SPI-Consumer = </strong>*</li>
-<li>When found, every call to java.util.ServiceLoader.load() will be modified automatically

-to have the ThreadContextClassLoader set to have visibility of the right bundles.</li>
+<li><strong>SPI-Consumer: </strong>* This is a shorthand for 
+<tt>java.util.ServiceLoader#load(java.lang.Class)</tt> and will 
+automatically weave all <tt>ServiceLoader.load(Class)</tt> calls.</li>
+<li><strong>java.util.ServiceLoader#load(java.lang.Class[org.apache.aries.mytest.MySPI])</strong>
+Only process calls to <tt>ServiceLoader.load(Class)</tt> when it is called with

+<tt>MySPI.class</tt> as argument.</li>
+<li><strong>javax.xml.parsers.DocumentBuilderFactory#newInstance()</strong>
weave clients that
+call <tt>DocumentBuilderFactory.newInstance()</tt>. </li>
+<li><strong>org.foo.Foo#someMthd(),org.bar.Bar#myMethod()</strong> weave
calls to <tt>Foo.someMthd()</tt> and 
+<tt>Bar.myMethod()</tt>. </li>
 </ul>
+<p>There are currently standardization efforts ongoing in the OSGi Alliance for which
the SPI Fly project is the Reference Implementation. 
+For more information, see RFC 167 in the OSGi Enterprise 5 EA draft: 
+<a href="http://www.osgi.org/download/osgi-early-draft-2011-09.pdf">http://www.osgi.org/download/osgi-early-draft-2011-09.pdf</a></p>
+<p>The code can be found in
+<a href="http://svn.apache.org/repos/asf/aries/trunk/spi-fly">http://svn.apache.org/repos/asf/aries/trunk/spi-fly</a>.</p>
 <h2 id="how_to_use">How to use</h2>
-<p>There are currently two ways to use the SPI-Fly component. If you have an OSGi 
-4.3 compliant framework that supports WeavingHooks you can use the dynamic weaving bundle.
</p>
+<p>There are currently two ways to use the SPI Fly component. If you have an OSGi 
+4.3 compliant framework that supports WeavingHooks you can use the dynamic weaving approach.
</p>
 <p>If you have an pre-4.3 OSGi framework or don't want to use bytecode weaving at runtime
you 
 can use the static weaving approach.</p>
 <h2 id="use_with_dynamic_weaving">Use with Dynamic Weaving</h2>
@@ -294,8 +332,12 @@ id  State       Bundle
 3   ACTIVE      org.apache.aries.spifly.dynamic.bundle_0.4.0.SNAPSHOT
 </pre>
 
+<p>Note that, as with any OSGi Bundle that uses the OSGi 4.3 WeavingHooks, the weaver
+bundle (<tt>org.apache.aries.spifly.dynamic.bundle</tt> in the SPI Fly case)
needs to 
+be active before any bundles that need to be dynamically woven. OSGi Start Levels can
+provide a mechanism to control this.</p>
 <h2 id="use_with_static_weaving">Use with Static Weaving</h2>
-<p>For static use, you need to modify the client bundle before installing it into the
system. 
+<p>For static use, you need to weave the client bundle before installing it into the
system. 
 The modification changes the byte code around java.util.ServiceLoader.load() calls in the

 bundle and inserts calls to set the correct ThreadContextClassLoader around it.
 Provider bundles are still handled dynamically.</p>



Mime
View raw message