blob: e9d4417094633c6b81733a9878a942b360084220 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<link rel="shortcut icon" href="http://aries.apache.org/images/favicon.ico"></link>
<link type="text/css" rel="stylesheet" href="http://aries.apache.org/resources/site.css"></link>
</script><script src="http://aries.apache.org/resources/menus.js" language="javascript" type="text/javascript"></script>
<meta name="keywords" content="..."/>
<meta name="description" content="..." />
<title>
Apache Aries - SPI Fly
</title>
</head>
<body onload="SetMenu()">
<table width="100%" cellpadding="0" cellspacing="0">
<tr width="100%">
<td id="cell-0-0" colspan="2">&nbsp;</td>
<td id="cell-0-1">&nbsp;</td>
<td id="cell-0-2" colspan="2">&nbsp;</td>
</tr>
<tr width="100%">
<td id="cell-1-0">&nbsp;</td>
<td id="cell-1-1">&nbsp;</td>
<td id="cell-1-2">
<div style="padding: 5px;">
<div id="banner">
<!-- Banner -->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td align="left" class="topbardiv" nowrap="">
<a href="http://aries.apache.org/" title="Apache Aries"> <img border="0" src="http://aries.apache.org/images/Arieslogo_Horizontal.gif"> </a>
</td>
<td align="right" nowrap="">
<a href="http://www.apache.org/" title="The Apache Software Foundation"> <img border="0" src="http://aries.apache.org/images/apache_feather.png"> </a>
</td>
</tr>
</table>
<!-- Banner -->
</div>
</div>
<div id="top-menu">
<table border="0" cellpadding="1" cellspacing="0" width="100%">
<tr>
<td>
<div align="left">
<!-- Breadcrumbs -->
<!-- Breadcrumbs -->
</div>
</td>
<td>
<div align="right">
<!-- Quicklinks -->
<DIV style="padding: 5px 5px 0px 25px;">
<FORM action="http://www.google.com/search" method="get" style="font-size: 10px;">
<A href="http://www.apache.org/licenses/LICENSE-2.0.html" class="external-link" rel="nofollow">License</A>
<INPUT name="ie" type="hidden" value="UTF-8"></INPUT>
<INPUT name="oe" type="hidden" value="UTF-8"></INPUT>
<INPUT maxlength="255" name="q" size="15" type="text" value></INPUT>
<INPUT name="btnG" type="submit" value="Search"></INPUT>
<INPUT name="domains" type="hidden" value="aries.apache.org"></INPUT>
<INPUT name="sitesearch" type="hidden" value="aries.apache.org"></INPUT>
</FORM>
</DIV>
<!-- Quicklinks -->
</div>
</td>
</tr>
</table>
</div>
</td>
<td id="cell-1-3">&nbsp;</td>
<td id="cell-1-4">&nbsp;</td>
</tr>
<tr width="100%">
<td id="cell-2-0" colspan="2">&nbsp;</td>
<td id="cell-2-1">
<table>
<tr height="100%" valign="top">
<td height="100%">
<div id="wrapper-menu-page-right">
<div id="wrapper-menu-page-top">
<div id="wrapper-menu-page-bottom">
<div id="menu-page">
<!-- NavigationBar -->
<style type="text/css">
/* The following code is added by mdx_elementid.py
It was originally lifted from http://subversion.apache.org/style/site.css */
/*
* Hide class="elementid-permalink", except when an enclosing heading
* has the :hover property.
*/
.headerlink, .elementid-permalink {
visibility: hidden;
}
h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
<div onclick="SwitchMenu('documentation')" id="documentationTitle" class="menutitle">Documentation</div>
<div id="documentation" class="menuitemgroup">
<div class="menuitem">
<a href="/documentation/integrators-guide.html">Integrators Guide</a>
</div>
<div class="menuitem">
<a href="/documentation/articles.html">Articles</a>
</div>
<div class="menuitem">
<a href="https://svn.apache.org/repos/asf/aries/slides/">Slides</a>
</div>
<div class="menuitem">
<a href="/documentation/tutorials.html">Tutorials</a>
</div>
<div class="menuitem">
<a href="/documentation/tools.html">Tools</a>
</div>
</div>
<div onclick="SwitchMenu('modules')" id="modulesTitle" class="menutitle">Modules</div>
<div id="modules" class="menuitemgroup">
<div class="menuitem">
<a href="/modules/samples.html">Samples</a>
</div>
<div class="menuitem">
<a href="/modules/async-svcs.html">Asynchronous Services</a>
</div>
<div class="menuitem">
<a href="/modules/blueprint.html">Blueprint</a>
</div>
<div class="menuitem">
<a href="/modules/blueprint-maven-plugin.html">Blueprint-maven-plugin</a>
</div>
<div class="menuitem">
<a href="/modules/blueprintannotation.html">Blueprint Annotations</a>
</div>
<div class="menuitem">
<a href="/modules/blueprintnoosgi.html">Blueprint No-OSGi</a>
</div>
<div class="menuitem">
<a href="/modules/blueprintweb.html">Blueprint Web</a>
</div>
<div class="menuitem">
<a href="/modules/esaanttask.html">ESA Ant Task </a>
</div>
<div class="menuitem">
<a href="/modules/ebamavenpluginproject.html">EBA Maven Plugin </a>
</div>
<div class="menuitem">
<a href="/modules/esamavenpluginproject.html">ESA Maven Plugin </a>
</div>
<div class="menuitem">
<a href="/modules/jmx.html">JMX</a>
</div>
<div class="menuitem">
<a href="/modules/jndiproject.html">JNDI</a>
</div>
<div class="menuitem">
<a href="/modules/jpaproject.html">JPA</a>
</div>
<div class="menuitem">
<a href="/modules/transactionsproject.html">Transactions</a>
</div>
<div class="menuitem">
<a href="/modules/spi-fly.html">SPI Fly</a>
</div>
<div class="menuitem">
<a href="/modules/subsystems.html">Subsystems</a>
</div>
<div class="menuitem">
<a href="/modules/applications.html">Applications (obsolete)</a>
</div>
</div>
<div onclick="SwitchMenu('downloads')" id="downloadsTitle" class="menutitle">Downloads</div>
<div id="downloads" class="menuitemgroup">
<div class="menuitem">
<a href="/downloads/currentreleases.html">Current Releases</a>
</div>
<div class="menuitem">
<a href="/downloads/testresults.html">Compliance Tests</a>
</div>
<div class="menuitem">
<a href="/downloads/archived-releases.html">Archived Releases</a>
</div>
</div>
<div onclick="SwitchMenu('community')" id="communityTitle" class="menutitle">Community</div>
<div id="community" class="menuitemgroup">
<div class="menuitem">
<a href="/community/resources.html">Community Resources</a>
</div>
<div class="menuitem">
<a href="/community/gettinginvolved.html">Getting Involved</a>
</div>
<div class="menuitem">
<a href="/community/people.html">Who we are</a>
</div>
<div class="menuitem">
<a href="/community/boardreports.html">Board Reports</a>
</div>
<div class="menuitem">
<a href="/community/logos.html">Logos for Users</a>
</div>
</div>
<div onclick="SwitchMenu('development')" id="developmentTitle" class="menutitle">Development</div>
<div id="development" class="menuitemgroup">
<div class="menuitem">
<a href="/development/buildingaries.html">Building Aries </a>
</div>
<div class="menuitem">
<a href="/development/guidelines.html">Cording Guidelines</a>
</div>
<div class="menuitem">
<a href="/development/architecture.html">Architecture</a>
</div>
<div class="menuitem">
<a href="/development/releasingaries.html">Releasing Aries </a>
</div>
<div class="menuitem">
<a href="/development/compliancetesting.html">OSGi Compliance Tests </a>
</div>
<div class="menuitem">
<a href="/development/maintainingthewebpages.html">Web Site Maintenance </a>
</div>
</div>
<div onclick="SwitchMenu('sponsorship')" id="sponsorshipTitle" class="menutitle">Sponsorship</div>
<div id="sponsorship" class="menuitemgroup">
<div class="menuitem">
<a href="http://www.apache.org/foundation/thanks.html">Thanks</a>
</div>
<div class="menuitem">
<a href="http://www.apache.org/foundation/sponsorship.html">Sponsoring Apache</a>
</div>
</div>
<!-- NavigationBar -->
</div>
</div>
</div>
</div>
</td>
<td height="100%" width="100%">
<!-- Content -->
<div class="wiki-content"><style type="text/css">
/* The following code is added by mdx_elementid.py
It was originally lifted from http://subversion.apache.org/style/site.css */
/*
* Hide class="elementid-permalink", except when an enclosing heading
* has the :hover property.
*/
.headerlink, .elementid-permalink {
visibility: hidden;
}
h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
<h1 id="spi-fly">SPI Fly<a class="headerlink" href="#spi-fly" title="Permanent link">&para;</a></h1>
<p>This page describes the SPI Fly component.
The SPI Fly component is aimed at providing OSGi support for JRE SPI
mechanisms, including the usage of <tt>java.util.ServiceLoader</tt>,
<tt>META-INF/services</tt> and similar methods.</p>
<p>SPI Fly is the Reference Implementation of the OSGi ServiceLoader Mediator specification, chapter 133 in the <a href="http://www.osgi.org/Download/Release5" title="OSGi Enterprise Specification">OSGi
Enterprise Specification</a>, available from version 5.</p>
<h2 id="the-problem">The Problem<a class="headerlink" href="#the-problem" title="Permanent link">&para;</a></h2>
<p>Java's <tt>java.util.ServiceLoader.load()</tt>, other similar methods such as
<tt>sun.misc.Service.providers()</tt> and 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 the above mechanisms when used 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 generally 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<a class="headerlink" href="#making-it-work" title="Permanent link">&para;</a></h2>
<p>In order to make ServiceLoader (and other similar SPI or plugin mechanisms) 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>
<p>SPI Fly supports two modes of operation:</p>
<ul>
<li>OSGi Specification compliant configuration. This is based on OSGi generic requirements and capabilities and
provides portability across implementations of this specification. However, it only covers <tt>java.util.ServiceLoader</tt>. <a href="#specconf">Find it here</a>.</li>
<li>If you need to handle cases other than <tt>java.util.ServiceLoader</tt>, such as the various FactoryFinders,
<tt>javax.imageio.spi.ServiceRegistry</tt>, <tt>javax.sound.sampled.AudioSystem</tt> or others that use the TCCL
to find an implementation, you can use the <a href="#specificconf">SPI Fly-specific configuration</a>.</li>
</ul>
<p>Additionally, services found in the META-INF/services location in opted-in bundles will be registered in the OSGi Service
Registry so that OSGi-aware consumers can simply find them there. This is supported in both the spec-compliant as
well as the proprietary configuration modes. Each such service is registered in the OSGi Service Registry with
the <em>serviceloader.mediator</em> service registration property set.</p>
<h2 id="getting-spi-fly">Getting SPI Fly<a class="headerlink" href="#getting-spi-fly" title="Permanent link">&para;</a></h2>
<h3 id="releases"><a id="releases"></a>Releases<a class="headerlink" href="#releases" title="Permanent link">&para;</a></h3>
<p>The latest release of the SPI-Fly components is 1.0.2. It can be obtained from Maven
Central using the links below.</p>
<p>To use SPI Fly you need to decide whether to use the dynamic or static weaving version.
More information about this can be found in the <a href="#usage">usage section</a>.</p>
<p><strong>For use with dynamic weaving:</strong></p>
<ul>
<li><a href="http://repo1.maven.org/maven2/org/apache/aries/spifly/org.apache.aries.spifly.dynamic.bundle/1.0.2/org.apache.aries.spifly.dynamic.bundle-1.0.2.jar">SPI Fly Dynamic Weaving Bundle 1.0.2</a></li>
</ul>
<p>Dependencies:</p>
<ul>
<li><a href="http://repo1.maven.org/maven2/org/apache/aries/org.apache.aries.util/1.1.1/org.apache.aries.util-1.1.1.jar">Aries Util 1.1.1</a></li>
<li><a href="http://repo1.maven.org/maven2/org/ow2/asm/asm-all/5.0.4/asm-all-5.0.4.jar">ASM 5.0.4</a></li>
</ul>
<p><strong>For use with static weaving:</strong></p>
<ul>
<li><a href="http://repo1.maven.org/maven2/org/apache/aries/spifly/org.apache.aries.spifly.static.tool/1.0.2/org.apache.aries.spifly.static.tool-1.0.2-jar-with-dependencies.jar">SPI Fly Static Weaving command-line tool 1.0.2</a></li>
<li><a href="http://repo1.maven.org/maven2/org/apache/aries/spifly/org.apache.aries.spifly.static.bundle/1.0.2/org.apache.aries.spifly.static.bundle-1.0.2.jar">SPI Fly Static Weaving Bundle 1.0.2</a></li>
</ul>
<p>Dependencies:</p>
<ul>
<li><a href="http://repo1.maven.org/maven2/org/apache/aries/org.apache.aries.util/1.1.1/org.apache.aries.util-1.1.1.jar">Aries Util 1.1.1</a></li>
</ul>
<h3 id="building-the-code">Building the code<a class="headerlink" href="#building-the-code" title="Permanent link">&para;</a></h3>
<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>To build, use Maven 3.x and run <tt>mvn install</tt></p>
<h1 id="configuration-osgi-spec-compliant"><a id="specconf"></a>Configuration: OSGi Spec-compliant<a class="headerlink" href="#configuration-osgi-spec-compliant" title="Permanent link">&para;</a></h1>
<p>All the details surrounding this type of configuration are covered in the
<a href="http://www.osgi.org/Download/Release5" title="OSGi Enterprise Specification">OSGi Enterprise Specification</a> (from version 5) chapter 133. This section provides a short overview.</p>
<h2 id="providers">Providers<a class="headerlink" href="#providers" title="Permanent link">&para;</a></h2>
<p>SPI provider bundles opt in to being registered by specifying a requirement on the
<tt>osgi.serviceloader.registrar</tt> extender. This is done by adding the following Bundle Manifest header. Without this they will not be considered by SPI Fly:</p>
<p><tt>&nbsp;&nbsp;Require-Capability: osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)"</tt></p>
<p>Additionally, they need to provide capabilities for all the APIs that are exposed through this mechanism, for example:</p>
<p><tt>&nbsp;&nbsp;Provide-Capability: osgi.serviceloader; osgi.serviceloader=org.apache.aries.spifly.mysvc.MySPIProvider</tt></p>
<p>While this example omits it, it is advisable to specify <tt>uses</tt> constraints on the Provide-Capability header, to
ensure consistent class spaces.</p>
<p>See the <a href="#examples"><tt>spi-fly-example-provider2-bundle</tt></a> for an example of a spec-compliant provider.</p>
<h2 id="consumers">Consumers<a class="headerlink" href="#consumers" title="Permanent link">&para;</a></h2>
<p>An SPI consumer (i.e. a bundle using the <tt>java.util.ServiceLoader.load()</tt> API) needs to specify required capabilities
in the Required-Capability Manifest header. Two different types of requirements must be specified:</p>
<ul>
<li>A requirement on the SPI Fly processing mechanism. This is stated as follows<br/>
<tt>&nbsp;&nbsp;osgi.extender; filter:="(osgi.extender=osgi.serviceloader.processor)"</tt><br/>
without this requirement the bundle will not be considered for processing.</li>
<li>A requirement on the SPI that needs to be provided through this mechanism, for example<br/>
<tt>&nbsp;&nbsp;osgi.serviceloader; filter:="(osgi.serviceloader=org.apache.aries.spifly.mysvc.MySPIProvider)";cardinality:=multiple</tt><br/>
Note that the <tt>cardinality</tt> directive is specified to allow multiple bundles to provide the requested capability, allowing
provided services to come from more than one provider bundle.</li>
</ul>
<p>All requirements are combined into a single Require-Capability header:</p>
<p><tt>&nbsp;&nbsp;Require-Capability: osgi.serviceloader; filter:="(osgi.serviceloader=org.apache.aries.spifly.mysvc.MySPIProvider)";cardinality:=multiple,osgi.extender; filter:="(osgi.extender=osgi.serviceloader.processor)"</tt></p>
<p>See the <a href="#examples"><tt>spi-fly-example-client2-bundle</tt></a> for an example of a spec-compliant consumer.</p>
<h1 id="configuration-spi-fly-specific"><a id="specificconf"></a>Configuration: SPI Fly-specific<a class="headerlink" href="#configuration-spi-fly-specific" title="Permanent link">&para;</a></h1>
<p>This section describes how to use SPI Fly's proprietary configuration
mechanism. It provides more features, but doesn't provide the
portability that spec-compliance configuration gives. If you
are only using SPI Fly with <tt>java.util.ServiceLoader</tt> or you are only using the provided
services through the OSGi Service Registry, then consider
using the <a href="#specconf">spec-compliant</a> configuration for portability.</p>
<h2 id="providers_1">Providers<a class="headerlink" href="#providers_1" title="Permanent link">&para;</a></h2>
<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><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>Additionally services found in META-INF/services are registered in the OSGi Service
Registry.</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>
<p>See the <a href="#examples"><tt>spi-fly-example-provider1-bundle</tt></a> for an example of a provider using this type of configuration.</p>
<h2 id="consumers_1">Consumers<a class="headerlink" href="#consumers_1" title="Permanent link">&para;</a></h2>
<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). Some example SPI-Consumer headers are:</p>
<ul>
<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>SPI-Consumer: 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>SPI-Consumer: javax.xml.parsers.DocumentBuilderFactory#newInstance()</strong> weave clients that
call <tt>DocumentBuilderFactory.newInstance()</tt>. </li>
<li><strong>SPI-Consumer: org.foo.Foo#someMthd(),org.bar.Bar#myMethod()</strong> weave calls to <tt>Foo.someMthd()</tt> and
<tt>Bar.myMethod()</tt>.</li>
</ul>
<p>See the <a href="#examples"><tt>spi-fly-example-client1-bundle</tt></a> for an example of a consumer using this type of configuration. </p>
<h3 id="special-cases">Special Cases<a class="headerlink" href="#special-cases" title="Permanent link">&para;</a></h3>
<p>SPI Fly can be used for most SPI provider/lookup systems that use the TCCL pattern to obtain
implementations. However, some cases some <em>special treatment</em> is needed. This special treatment is often needed when the API itself does not
match the name of the resources in META-INF/services, java.util.ServiceLoader is such a case, however SPI-Fly has built-in knowledge of ServiceLoader.
Known APIs that require special treatment are listed below:</p>
<ul>
<li><strong>javax.imageio.spi.ServiceRegistry</strong>: This class is very much like
java.util.ServiceLoader in that it can load any kind of API implementation.
While SPI Fly knows about ServiceLoader and treats it specially, the ServiceRegistry
class currently does not have special treatment. It can still be made to work
but this requires the following header in the provider bundle:
<tt>SPI-Provider:&nbsp;javax.imageio.spi.ServiceRegistry</tt> on the client
side you can use <tt>SPI-Consumer:&nbsp;javax.imageio.spi.ServiceRegistry#lookupProviders(java.lang.Class)</tt>
or <tt>SPI-Consumer:&nbsp;javax.imageio.spi.ServiceRegistry#lookupProviders</tt></li>
<li><strong>javax.sound.sampled.AudioSystem</strong>: This class uses sun.misc.Service under the covers (via com.sun.media.sound.JDK13Services)
which is a predecessor to java.util.ServiceLoader. There is no special treatment for sun.misc.Service
in SPI Fly (yet), but the AudioSystem.getAudioInputStream() API can be made to work by explicitly listing it in the provider bundle
(the one that contains the relevant META-INF/services resources):
<tt>SPI-Provider:&nbsp;javax.sound.sampled.AudioSystem</tt> on the consumer side you can use
<tt>SPI-Consumer:&nbsp;javax.sound.sampled.AudioSystem#getAudioInputStream
</tt></li>
</ul>
<h1 id="usage"><a id="usage"></a>Usage<a class="headerlink" href="#usage" title="Permanent link">&para;</a></h1>
<p>There are currently two ways to use the SPI Fly component. If you have an OSGi
4.3 (or higher) 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<a class="headerlink" href="#use-with-dynamic-weaving" title="Permanent link">&para;</a></h2>
<p>Install and start the <a href="#releases"><tt>org.apache.aries.spifly.dynamic.bundle</tt></a> into the system. This bundle
has a dependency on <tt><a href="http://search.maven.org/#artifactdetails%7Corg.ow2.asm%7Casm-all%7C5.0.4%7Cjar">org.objectweb.asm</a></tt> version 4.0 or newer and on the Aries
Util bundle.</p>
<pre>g! lb
START LEVEL 1
ID|State |Level|Name
0|Active | 0|System Bundle (5.0.1)
... bundles 1-4 are framework/console internal ones ...
5|Active | 1|ASM all classes (5.0.4)
6|Active | 1|Apache Aries Util (1.1.1)
7|Active | 1|Apache Aries SPI Fly Dynamic Weaving Bundle (1.0.2)
</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<a class="headerlink" href="#use-with-static-weaving" title="Permanent link">&para;</a></h2>
<p>For static use, you need to weave the client bundle before installing it into the system.
The modification changes the byte code around <tt>java.util.ServiceLoader.load()</tt> or other calls in the
bundle and inserts calls to set the correct ThreadContextClassLoader around it.
Provider bundles are still handled dynamically.</p>
<h3 id="to-statically-weave-a-bundle">To statically weave a bundle<a class="headerlink" href="#to-statically-weave-a-bundle" title="Permanent link">&para;</a></h3>
<p>The easiest way to invoke the static weaver is to take the <a href="#releases"><tt>org.apache.aries.spifly.static.tool</tt></a>
jar with dependencies.</p>
<p>Then run the static tool on any bundle that needs processing:
<pre>
java -jar org.apache.aries.spifly.static.tool-1.0.2-jar-with-dependencies.jar mybundle.jar
</pre></p>
<p>This will produce a second bundle with the same name with the _spifly suffix appended, so
in this case the generated bundle will be called mybundle_spifly.jar.</p>
<p>At runtime, install the <a href="#releases"><tt>org.apache.aries.spifly.static.bundle</tt></a> into the system, like
the dynamic weaving bundle it has a dependency on the Aries Util bundle:
<pre>g! lb
START LEVEL 1
ID|State |Level|Name
0|Active | 0|System Bundle (5.0.1)
... bundles 1-4 are framework/console internal ones ...
5|Active | 1|Apache Aries Util (1.1.1)
6|Active | 1|Apache Aries SPI Fly Static Weaving Bundle (1.0.2)</pre></p>
<p>Then install and start the statically woven bundle into the system.</p>
<h2 id="examples"><a id="examples"></a>Examples<a class="headerlink" href="#examples" title="Permanent link">&para;</a></h2>
<p>The <tt>spi-fly-examples</tt> directory contains a number of example bundles that can be
used for testing or experimenting.</p>
<p>The following modules can be found in this directory:</p>
<ul>
<li><strong>spi-fly-example-spi-bundle</strong> - a bundle providing an SPI interface used by the other example bundles. <a href="http://search.maven.org/remotecontent?filepath=org/apache/aries/spifly/examples/org.apache.aries.spifly.examples.spi.bundle/1.0.0/org.apache.aries.spifly.examples.spi.bundle-1.0.0.jar">osgi-bundle</a> <a href="http://svn.apache.org/repos/asf/aries/trunk/spi-fly/spi-fly-examples/spi-fly-example-spi-bundle/">source</a></li>
<li><strong>spi-fly-example-provider1-jar</strong> - a plain jar file providing an implementation of the SPI (via <tt>META-INF/services</tt>). <a href="http://svn.apache.org/repos/asf/aries/trunk/spi-fly/spi-fly-examples/spi-fly-example-provider1-jar/">source</a></li>
<li><strong>spi-fly-example-provider1-bundle</strong> - a bundle that wraps the jar file from the previous bullet and specifies it in its Bundle-ClassPath. This example represents the common case where an existing SPI provider is wrapped as-is in an OSGi bundle. This example uses the SPI Fly proprietary configuration. <a href="http://search.maven.org/remotecontent?filepath=org/apache/aries/spifly/examples/org.apache.aries.spifly.examples.provider1.bundle/1.0.0/org.apache.aries.spifly.examples.provider1.bundle-1.0.0.jar">osgi-bundle</a> <a href="http://svn.apache.org/repos/asf/aries/trunk/spi-fly/spi-fly-examples/spi-fly-example-provider1-bundle/">source</a></li>
<li><strong>spi-fly-example-provider2-bundle</strong> - a bundle that directly provides an SPI service (via <tt>META-INF/services</tt>). This example uses OSGi specification compliant configuration. <a href="http://search.maven.org/remotecontent?filepath=org/apache/aries/spifly/examples/org.apache.aries.spifly.examples.provider2.bundle/1.0.0/org.apache.aries.spifly.examples.provider2.bundle-1.0.0.jar">osgi-bundle</a> <a href="http://svn.apache.org/repos/asf/aries/trunk/spi-fly/spi-fly-examples/spi-fly-example-provider2-bundle/">source</a> </li>
<li><strong>spi-fly-example-client1-jar</strong> - a plain jar using java.util.ServiceLoader.load() to obtain and invoke all services provided of a certain SPI. <a href="http://svn.apache.org/repos/asf/aries/trunk/spi-fly/spi-fly-examples/spi-fly-example-client1-jar/">source</a></li>
<li><strong>spi-fly-example-client1-bundle</strong> - a bundle that wraps the jar file from the previous bullet and lists it in its Bundle-ClassPath. This example represents the common case where an existing SPI consumer is wrapped as-is in an OSGi bundle. This example uses SPI Fly proprietary configuration. <a href="http://search.maven.org/remotecontent?filepath=org/apache/aries/spifly/examples/org.apache.aries.spifly.examples.client1.bundle/1.0.0/org.apache.aries.spifly.examples.client1.bundle-1.0.0.jar">osgi-bundle</a> <a href="http://svn.apache.org/repos/asf/aries/trunk/spi-fly/spi-fly-examples/spi-fly-example-client1-bundle/">source</a></li>
<li><strong>spi-fly-example-client2-bundle</strong> - a bundle that has code that invokes <tt>java.util.ServiceLoader.load()</tt> directly. This example uses OSGi specification compliant configuration. <a href="http://search.maven.org/remotecontent?filepath=org/apache/aries/spifly/examples/org.apache.aries.spifly.examples.client2.bundle/1.0.0/org.apache.aries.spifly.examples.client2.bundle-1.0.0.jar">osgi-bundle</a> <a href="http://svn.apache.org/repos/asf/aries/trunk/spi-fly/spi-fly-examples/spi-fly-example-client2-bundle/">source</a></li>
<li><strong>spi-fly-example-provider-consumer-bundle</strong> - a bundle that is both a provider and a consumer at the same time. <a href="http://svn.apache.org/repos/asf/aries/trunk/spi-fly/spi-fly-examples/spi-fly-example-provider-consumer-bundle/">source</a></li>
<li><strong>spi-fly-example-resource-provider-bundle</strong> and <strong>spi-fly-example-resource-client-bundle</strong> - these bundles show that SPI Fly can be used to control the TCCL in OSGi for any situation, in this case applied to resource loading via the TCCL. The provider bundle provides a resource used by the Foo.doit() API. The client bundle contains Foo.doit() and in there calls Thread.getContextClassLoader().getResource() to obtain the resource. The TCCL has visibility of the provider bundle because both bundles have the appropriate values set in the SPI-Provider and SPI-Consumer headers. Source <a href="http://svn.apache.org/repos/asf/aries/trunk/spi-fly/spi-fly-examples/spi-fly-example-resource-provider-bundle/">here</a> and <a href="http://svn.apache.org/repos/asf/aries/trunk/spi-fly/spi-fly-examples/spi-fly-example-resource-client-bundle/">here</a>.</li>
</ul>
<h2 id="more-information">More Information<a class="headerlink" href="#more-information" title="Permanent link">&para;</a></h2>
<p>More information can be found at the following resources:</p>
<ul>
<li>OSGi Service Loader Mediator specification. <a href="http://www.osgi.org/Download/Release5">OSGi Enterprise specification</a>, Chapter 133.</li>
<li>OSGi Blog article: <a href="http://blog.osgi.org/2013/02/javautilserviceloader-in-osgi.html">http://blog.osgi.org/2013/02/javautilserviceloader-in-osgi.html</a></li>
</ul></div>
<!-- Content -->
</td>
</tr>
</table>
</td>
<td id="cell-2-2" colspan="2">&nbsp;</td>
</tr>
<tr width="100%">
<td id="cell-3-0">&nbsp;</td>
<td id="cell-3-1">&nbsp;</td>
<td id="cell-3-2">
<div id="footer">
<!-- Footer -->
<div id="site-footer">
<a href="http://aries.apache.org/privacy-policy.html";>Privacy
Policy</a>
</div>
<!-- Footer -->
</div>
</td>
<td id="cell-3-3">&nbsp;</td>
<td id="cell-3-4">&nbsp;</td>
</tr>
<tr width="100%">
<td id="cell-4-0" colspan="2">&nbsp;</td>
<td id="cell-4-1">&nbsp;</td>
<td id="cell-4-2" colspan="2">&nbsp;</td>
</tr>
</table>
</body>
</html>