| <!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 - |
| </title> |
| </head> |
| <body onload="SetMenu()"> |
| |
| <table width="100%" cellpadding="0" cellspacing="0"> |
| <tr width="100%"> |
| <td id="cell-0-0" colspan="2"> </td> |
| <td id="cell-0-1"> </td> |
| <td id="cell-0-2" colspan="2"> </td> |
| </tr> |
| <tr width="100%"> |
| <td id="cell-1-0"> </td> |
| <td id="cell-1-1"> </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"> </td> |
| <td id="cell-1-4"> </td> |
| </tr> |
| <tr width="100%"> |
| <td id="cell-2-0" colspan="2"> </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/containers.html">Containers</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/transactioncontrol.html">Transaction Control Service</a> |
| </div> |
| <div class="menuitem"> |
| <a href="/modules/transactionsproject.html">Transactions</a> |
| </div> |
| <div class="menuitem"> |
| <a href="/modules/rsa.html">Remote Service Admin (RSA)</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> |
| |
| <div class="promotion"> |
| <a href="http://www.apache.org/events/current-event.html"> |
| <img src="http://www.apache.org/events/current-event-125x125.png" width="125" height="125"/> |
| </a> |
| </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> |
| <p>Title: Asynchronous Services</p> |
| <h1 id="introduction">Introduction<a class="headerlink" href="#introduction" title="Permanent link">¶</a></h1> |
| <p>The R6 OSGi specifications include support for Asynchronous programming using OSGi services. |
| Apache Aries aims to provide small, compliant implementations of these specifications to enable asynchronous |
| programming in enterprise applications. The two key specifications are OSGi Promises and the Async service.</p> |
| <h1 id="osgi-promises">OSGi Promises<a class="headerlink" href="#osgi-promises" title="Permanent link">¶</a></h1> |
| <p>One of the fundamental pieces of an asynchronous programming system is the <em>Promise</em>. A Promise is a holder type that |
| represents an asynchronous calculation or computation. Since Java 5 the JDK has contained <em>java.util.concurrent.Future</em> to perform this |
| function. Java's Future type is, however, fatally flawed as it has no callback to notify the user when it resolves. Instead the |
| user must make a blocking call to <em>get()</em>.</p> |
| <p>OSGi promises fix this problem by defining a Promise interface which allows the user to register callbacks which will be |
| called when the promise <em>resolves</em>. These callbacks are lambda friendly SAM types, but the Promise API itself has no |
| dependencies on Java 8. The Aries version (org.apache.aries.async.promise.api) has a minimum requirement of JDK 6.</p> |
| <h2 id="creating-osgi-promises">Creating OSGi Promises<a class="headerlink" href="#creating-osgi-promises" title="Permanent link">¶</a></h2> |
| <p>Creating a Promise is easy. The <em>org.osgi.util.promise.Deferred</em> type is a factory for a single promise, and can also be used to |
| resolve or fail the promise:</p> |
| <div class="codehilite"><pre><span class="n">Deferred</span><span class="o"><</span><span class="n">Integer</span><span class="o">></span> <span class="n">deferred</span> <span class="p">=</span> <span class="n">new</span> <span class="n">Deferred</span><span class="o"><></span><span class="p">();</span> |
| <span class="n">new</span> <span class="n">Thread</span><span class="p">(()</span> <span class="o">-></span> <span class="p">{</span> |
| <span class="n">int</span> <span class="n">result</span> <span class="p">=</span> <span class="n">calculateReallyHardSum</span><span class="p">();</span> |
| <span class="n">deferred</span><span class="p">.</span><span class="n">resolve</span><span class="p">(</span><span class="n">result</span><span class="p">);</span> |
| <span class="p">}).</span><span class="n">start</span><span class="p">();</span> |
| |
| <span class="n">Promise</span><span class="o"><</span><span class="n">Integer</span><span class="o">></span> <span class="n">p</span> <span class="p">=</span> <span class="n">deferred</span><span class="p">.</span><span class="n">getPromise</span><span class="p">();</span> |
| <span class="p">...</span> |
| </pre></div> |
| |
| |
| <p>But wait - what if something goes wrong? How do we signal to the user that there was a problem and the result is never coming? |
| The answer is very easy - Promises have the concept of <em>failure</em>. A promise will <em>either</em> resolve <em>or</em> fail at most once. For well |
| written code this rule is usually the same as "A promise will either resolve or fail <em>exactly</em> once". Promises are thread safe and |
| effectively immutable, meaning they can be shared with other code.</p> |
| <div class="codehilite"><pre><span class="n">Deferred</span><span class="o"><</span><span class="n">Integer</span><span class="o">></span> <span class="n">deferred</span> <span class="p">=</span> <span class="n">new</span> <span class="n">Deferred</span><span class="o"><></span><span class="p">();</span> |
| <span class="n">new</span> <span class="n">Thread</span><span class="p">(()</span> <span class="o">-></span> <span class="p">{</span> |
| <span class="k">try</span> <span class="p">{</span> |
| <span class="n">int</span> <span class="n">result</span> <span class="p">=</span> <span class="n">calculateErrorProneSum</span><span class="p">();</span> |
| <span class="n">deferred</span><span class="p">.</span><span class="n">resolve</span><span class="p">(</span><span class="n">result</span><span class="p">);</span> |
| <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span> |
| <span class="n">deferred</span><span class="p">.</span><span class="n">fail</span><span class="p">(</span><span class="n">e</span><span class="p">);</span> |
| <span class="p">}</span> |
| <span class="p">}).</span><span class="n">start</span><span class="p">();</span> |
| |
| <span class="n">Promise</span><span class="o"><</span><span class="n">Integer</span><span class="o">></span> <span class="n">p</span> <span class="p">=</span> <span class="n">deferred</span><span class="p">.</span><span class="n">getPromise</span><span class="p">();</span> |
| <span class="p">...</span> |
| </pre></div> |
| |
| |
| <h2 id="using-osgi-promises">Using OSGi Promises<a class="headerlink" href="#using-osgi-promises" title="Permanent link">¶</a></h2> |
| <p>Once you have a promise, what do you do with it? It's easy to get the value from a promise using the <em>getValue()</em> method, |
| or you can use the <em>getFailure()</em> method to get the failure cause. Unfortunately both of these methods block until the promise |
| resolves, and whilst the <em>isDone()</em> method does tell you if the Promise has completed they really aren't the right way to use a |
| Promise.</p> |
| <p>Promises work best when you register callbacks and/or transformations. The Promise API has a variety of useful methods for |
| doing work with the Promise when it resolves. For example we can run a task after the promise completes successfully:</p> |
| <div class="codehilite"><pre><span class="n">Promise</span><span class="o"><</span><span class="n">Integer</span><span class="o">></span> <span class="n">promise</span> <span class="p">=</span> <span class="p">...</span> |
| <span class="n">promise</span><span class="p">.</span><span class="n">then</span><span class="p">(</span><span class="n">p</span> <span class="o">-></span> <span class="p">{</span> |
| <span class="n">System</span><span class="p">.</span><span class="n">out</span><span class="p">.</span><span class="n">println</span><span class="p">(</span>"<span class="n">The</span> <span class="n">calculator</span> <span class="n">returned</span> " <span class="o">+</span> <span class="n">p</span><span class="p">.</span><span class="n">getValue</span><span class="p">());</span> |
| <span class="k">return</span> <span class="n">null</span><span class="p">;</span> |
| <span class="p">});</span> |
| </pre></div> |
| |
| |
| <p>We can also register callbacks to handle failures:</p> |
| <div class="codehilite"><pre><span class="n">Promise</span><span class="o"><</span><span class="n">Integer</span><span class="o">></span> <span class="n">promise</span> <span class="p">=</span> <span class="p">...</span> |
| <span class="n">promise</span><span class="p">.</span><span class="n">then</span><span class="p">(</span><span class="n">p</span> <span class="o">-></span> <span class="p">{</span> |
| <span class="n">System</span><span class="p">.</span><span class="n">out</span><span class="p">.</span><span class="n">println</span><span class="p">(</span>"<span class="n">The</span> <span class="n">calculator</span> <span class="n">returned</span> " <span class="o">+</span> <span class="n">p</span><span class="p">.</span><span class="n">getValue</span><span class="p">());</span> |
| <span class="k">return</span> <span class="n">null</span><span class="p">;</span> |
| <span class="p">},</span> <span class="n">p</span> <span class="o">-></span> <span class="n">p</span><span class="p">.</span><span class="n">getFailure</span><span class="p">().</span><span class="n">printStackTrace</span><span class="p">());</span> |
| </pre></div> |
| |
| |
| <h3 id="chaining-osgi-promises">Chaining OSGi Promises<a class="headerlink" href="#chaining-osgi-promises" title="Permanent link">¶</a></h3> |
| <p>In the previous examples our success callback returned <em>null</em> - why? Well the return value from a success callback is always |
| a promise (null is a shortcut for a promise resolved with null). The promise returned by the callback represents an asynchronous |
| execution flow in a process known as "chaining". The overall completion of this chain is represented by a third promise, returned |
| to the caller of the <em>then()</em> method.</p> |
| <ol> |
| <li>The caller registers a success callback, and receives a "chained" promise</li> |
| <li>The original promise completes successfully</li> |
| <li>The success callback runs and returns a promise representing another piece of asynchronous work</li> |
| <li>The promise returned by the success callback completes successfully</li> |
| <li>The "chained" promise completes with the same value as the promise from step 4.</li> |
| </ol> |
| <h2 id="other-promise-behaviours">Other Promise behaviours<a class="headerlink" href="#other-promise-behaviours" title="Permanent link">¶</a></h2> |
| <p>As well as simple callbacks Promises also provide advanced mapping and recovery features. For example a promise can be |
| wrapped so that if the original work fails then a new value can be supplied using a recovery function.</p> |
| <p>The <em>org.osgi.util.promise.Promises</em> utility class also provides useful functions for working with promises. For example helper |
| methods to wrap an existing value or failure in a Promise, or a way of aggregating a group of promises into a single promise.</p> |
| <h1 id="the-async-service">The Async service<a class="headerlink" href="#the-async-service" title="Permanent link">¶</a></h1> |
| <p>Most OSGi services have a synchronous API. This is usually the easiest way to think about, write, and use services. The main |
| problem with this is that long running service calls can cause applications to run slowly, and making the calls asynchronous is |
| both verbose and error-prone.</p> |
| <p>The Async service is designed to take away the boilerplate code needed to invoke a service asynchronously, and to convert any |
| synchronous API into an asynchronous API, returning promises instead of values.</p> |
| <h2 id="using-the-async-service">Using the Async service<a class="headerlink" href="#using-the-async-service" title="Permanent link">¶</a></h2> |
| <p>The Async service is available in the service registry and is very easy to use - first we need to mediate the service. |
| Mediating is a bit like creating a mock object, the mediator records method calls made against it so that they can be |
| transformed into asynchronous calls. Mediating can apply to a concrete object, or to a ServiceReference. It is better to |
| use a ServiceReference when one is available, as the Async service can track the availability of the backing service.</p> |
| <div class="codehilite"><pre><span class="n">Async</span> <span class="n">async</span> <span class="p">=</span> <span class="p">...;</span> |
| <span class="n">ServiceReference</span><span class="o"><</span><span class="n">MyService</span><span class="o">></span> <span class="n">ref</span> <span class="p">=</span> <span class="p">...;</span> |
| <span class="n">MyService</span> <span class="n">mediator</span> <span class="p">=</span> <span class="n">async</span><span class="p">.</span><span class="n">mediate</span><span class="p">(</span><span class="n">ref</span><span class="p">,</span> <span class="n">MyService</span><span class="p">.</span><span class="n">class</span><span class="p">);</span> |
| </pre></div> |
| |
| |
| <p><em>or</em></p> |
| <div class="codehilite"><pre><span class="n">Async</span> <span class="n">async</span> <span class="p">=</span> <span class="p">...;</span> |
| <span class="n">MyService</span> <span class="n">svc</span> <span class="p">=</span> <span class="p">...;</span> |
| <span class="n">MyService</span> <span class="n">mediator</span> <span class="p">=</span> <span class="n">async</span><span class="p">.</span><span class="n">mediate</span><span class="p">(</span><span class="n">svc</span><span class="p">,</span> <span class="n">MyService</span><span class="p">.</span><span class="n">class</span><span class="p">);</span> |
| </pre></div> |
| |
| |
| <p>Once a service has been mediated the mediator should be called just like the real service object, and the return value passed to |
| the Async service's <em>call()</em> method. This returns a promise representing the asynchronous work.</p> |
| <div class="codehilite"><pre><span class="n">Promise</span><span class="o"><</span><span class="n">Integer</span><span class="o">></span> <span class="n">promise</span> <span class="p">=</span> <span class="n">async</span><span class="p">.</span><span class="n">call</span><span class="p">(</span><span class="n">mediator</span><span class="p">.</span><span class="n">calculateReallyHardSum</span><span class="p">());</span> |
| </pre></div> |
| |
| |
| <h3 id="void-methods">Void methods<a class="headerlink" href="#void-methods" title="Permanent link">¶</a></h3> |
| <p>Void methods don't have a return value to pass to the async service, and should use the no-args version of call instead.</p> |
| <div class="codehilite"><pre><span class="nx">mediator</span><span class="p">.</span><span class="nx">longRunningVoidMethod</span><span class="p">()</span> |
| <span class="nx">Promise</span><span class="cp"><?</span><span class="o">></span> <span class="nx">promise</span> <span class="o">=</span> <span class="nx">async</span><span class="o">.</span><span class="nx">call</span><span class="p">();</span> |
| </pre></div> |
| |
| |
| <h3 id="fire-and-forget-calls">Fire and Forget calls<a class="headerlink" href="#fire-and-forget-calls" title="Permanent link">¶</a></h3> |
| <p>Sometimes the user does not care when a piece of work finishes, or what value it returns, or even whether it was successful. |
| These sorts of calls are called "fire and forget" calls, and are also supported by the async service using the <em>execute()</em> method.</p> |
| <p>The execute method still returns a promise, however this promise represents whether the fire and forget call successfully started |
| or not, not whether it has completed.</p> |
| <h1 id="getting-started">Getting Started<a class="headerlink" href="#getting-started" title="Permanent link">¶</a></h1> |
| <p>Releases of the Async implementation can be found in Maven Central <a href="http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.apache.aries.async%22" title="org.apache.aries.async">in the org.apache.aries.async group</a>. <a href="http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22org.apache.aries.async%22">This bundle</a> provides a convenient all-in-one download.</p> |
| <p>The Asynchronous Services source code can be found in the Apache Aries codebase in the <code>async</code> directory: <a href="https://svn.apache.org/repos/asf/aries/trunk/async">https://svn.apache.org/repos/asf/aries/trunk/async</a></p></div> |
| <!-- Content --> |
| </td> |
| </tr> |
| </table> |
| </td> |
| <td id="cell-2-2" colspan="2"> </td> |
| </tr> |
| <tr width="100%"> |
| <td id="cell-3-0"> </td> |
| <td id="cell-3-1"> </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"> </td> |
| <td id="cell-3-4"> </td> |
| </tr> |
| <tr width="100%"> |
| <td id="cell-4-0" colspan="2"> </td> |
| <td id="cell-4-1"> </td> |
| <td id="cell-4-2" colspan="2"> </td> |
| </tr> |
| </table> |
| </body> |
| </html> |