blob: ca89f75a65fb2ab98332a824855d163f9d8593c9 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<title>Asynchronous</title>
<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
<script type="text/javascript" src="../../../script.js"></script>
<link rel="shortcut icon" href="/img/jakarta-favicon.ico">
</head>
<body>
<script type="text/javascript"><!--
try {
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="Asynchronous";
}
}
catch(err) {
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar.top">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.top" title="Skip navigation links">Skip navigation links</a></div>
<a name="navbar.top.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../overview-summary.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../index-all.html">Index</a></li>
<li><a href="../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="../../../jakarta/enterprise/concurrent/AbortedException.html" title="class in jakarta.enterprise.concurrent"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
<li><a href="../../../jakarta/enterprise/concurrent/Asynchronous.Result.html" title="class in jakarta.enterprise.concurrent"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
</ul>
<ul class="navList">
<li><a href="../../../index.html?jakarta/enterprise/concurrent/Asynchronous.html" target="_top">Frames</a></li>
<li><a href="Asynchronous.html" target="_top">No&nbsp;Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<div>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li>Required&nbsp;|&nbsp;</li>
<li><a href="#annotation.type.optional.element.summary">Optional</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#annotation.type.element.detail">Element</a></li>
</ul>
</div>
<a name="skip.navbar.top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<!-- ======== START OF CLASS DATA ======== -->
<div class="header">
<div class="subTitle">jakarta.enterprise.concurrent</div>
<h2 title="Annotation Type Asynchronous" class="title">Annotation Type Asynchronous</h2>
</div>
<div class="contentContainer">
<div class="description">
<ul class="blockList">
<li class="blockList">
<hr>
<br>
<pre>@Documented
@Inherited
<a href="../../../jakarta/interceptor/InterceptorBinding.html" title="annotation in jakarta.interceptor">@InterceptorBinding</a>
@Retention(value=RUNTIME)
@Target(value={METHOD,TYPE})
public @interface <span class="memberNameLabel">Asynchronous</span></pre>
<div class="block">Annotates a CDI managed bean method to run asynchronously.
The CDI managed bean must not be a Jakarta Enterprise Bean,
and neither the method nor its class can be annotated with
the MicroProfile Asynchronous annotation.
<p>
The Jakarta EE Product Provider runs the method on a <a href="../../../jakarta/enterprise/concurrent/ManagedExecutorService.html" title="interface in jakarta.enterprise.concurrent"><code>ManagedExecutorService</code></a>
and returns to the caller a <code>CompletableFuture</code>
that is backed by the same <code>ManagedExecutorService</code>
to represent the execution of the method. The <code>ManagedExecutorService</code>
is the default asynchronous execution facility for the <code>CompletableFuture</code>
and and all dependent stages that are created from those, and so on,
as defined by the <code>ManagedExecutorService</code> JavaDoc API.
The Jakarta EE Product Provider makes this <code>CompletableFuture</code> available
to the asynchronous method implementation via the
<a href="../../../jakarta/enterprise/concurrent/Asynchronous.Result.html#getFuture--"><code>Asynchronous.Result.getFuture</code></a> and
<a href="../../../jakarta/enterprise/concurrent/Asynchronous.Result.html#complete-T-"><code>Asynchronous.Result.complete</code></a> methods.
<p>
For example,
<pre>
@Asynchronous
public CompletableFuture &lt;Double&gt; hoursWorked(LocalDate from, LocalDate to) {
// Application component's context is made available to the async method,
try (Connection con = ((DataSource) InitialContext.doLookup(
"java:comp/env/jdbc/timesheetDB")).getConnection()) {
...
return Asynchronous.Result.complete(total);
} catch (NamingException | SQLException x) {
throw new CompletionException(x);
}
}
</pre>
with usage,
<pre>
hoursWorked(mon, fri).thenAccept(total -&gt; {
// Application component's context is made available to dependent stage actions,
DataSource ds = InitialContext.doLookup(
"java:comp/env/jdbc/payrollDB");
...
});
</pre>
When the asynchronous method implementation returns a different
<code>CompletableFuture</code> instance, the Jakarta EE Product Provider
uses the completion of that instance to complete the <code>CompletableFuture</code>
that the Jakarta EE Product Provider returns to the caller,
completing it with the same result or exception.
<p>
For example,
<pre>
@Asynchronous
public CompletableFuture &lt;List&lt;Itinerary&gt;&gt; findSingleLayoverFlights(Location source, Location dest) {
try {
ManagedExecutorService executor = InitialContext.doLookup(
"java:comp/DefaultManagedExecutorService");
return executor.supplyAsync(source::flightsFrom)
.thenCombine(executor.completedFuture(dest.flightsTo()),
Itinerary::sourceMatchingDest);
} catch (NamingException x) {
throw new CompletionException(x);
}
}
</pre>
with usage,
<pre>
findSingleLayoverFlights(RST, DEN).thenApply(Itinerary::sortByPrice);
</pre>
<p>
Methods with the following return types can be annotated to be
asynchronous methods:
<ul>
<li><code>CompletableFuture</code></li>
<li><code>CompletionStage</code></li>
<li><code>void</code></li>
</ul>
<p>
The Jakarta EE Product Provider raises
<code>UnsupportedOperationException</code>
if other return types are used or if the annotation is placed at the class
level. The injection target of <code>ElementType.TYPE</code> is to be used only
by the CDI extension that is implemented by the Jakarta EE Product Provider to
register the asynchronous method interceptor. Applications must only use the
asynchronous method annotation at method level.
<p>
Exceptions that are raised by asynchronous methods are not raised directly
to the caller because the method runs asynchronously to the caller.
Instead, the <code>CompletableFuture</code> that represents the result
is completed with the raised exception. Asynchronous methods are
discouraged from raising checked exceptions because checked exceptions
force the caller to write exception handling code that is unreachable.
When a checked exception occurs, the asynchronous method implementation
can flow the exception back to the resulting <code>CompletableFuture</code>
either by raising a
<code>CompletionException</code>
with the original exception as the cause, or it can take the equivalent
approach of exceptionally completing the <code>CompletableFuture</code>, using
<code>completeExceptionally</code>
to supply the original exception as the cause.
<p>
Except where otherwise stated, the Jakarta EE Product Provider raises
<code>RejectedExecutionException</code>
upon invocation of the asynchronous method if evident upfront that it cannot
be accepted, for example if the JNDI name is not valid or points to something
other than a managed executor resource. If determined at a later point that the
asynchronous method cannot run (for example, if unable to establish thread context),
then the Jakarta EE Product Provider completes the <code>CompletableFuture</code>
exceptionally with <code>CancellationException</code>,
and chains a cause exception if there is any.
<p>
The Jakarta EE Product Provider must assign the interceptor for asynchronous methods
to have priority of <code>Interceptor.Priority.PLATFORM_BEFORE + 5</code>.
Interceptors with a lower priority, such as <code>Transactional</code>, must run on
the thread where the asynchronous method executes, rather than on the submitting thread.
When an asynchronous method is annotated as <code>Transactional</code>,
the transactional types which can be used are:
<code>TxType.REQUIRES_NEW</code>, which causes the method to run in a new transaction, and
<code>TxType.NOT_SUPPORTED</code>, which causes the method to run with no transaction.
All other transaction attributes must result in
<code>UnsupportedOperationException</code>
upon invocation of the asynchronous method.</div>
<dl>
<dt><span class="simpleTagLabel">Since:</span></dt>
<dd>3.0</dd>
</dl>
</li>
</ul>
</div>
<div class="summary">
<ul class="blockList">
<li class="blockList">
<!-- =========== ANNOTATION TYPE OPTIONAL MEMBER SUMMARY =========== -->
<ul class="blockList">
<li class="blockList"><a name="annotation.type.optional.element.summary">
<!-- -->
</a>
<h3>Optional Element Summary</h3>
<table class="memberSummary" border="0" cellpadding="3" cellspacing="0" summary="Optional Element Summary table, listing optional elements, and an explanation">
<caption><span>Optional Elements</span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colLast" scope="col">Optional Element and Description</th>
</tr>
<tr class="altColor">
<td class="colFirst"><code>java.lang.String</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../jakarta/enterprise/concurrent/Asynchronous.html#executor--">executor</a></span></code>
<div class="block">JNDI name of a <a href="../../../jakarta/enterprise/concurrent/ManagedExecutorService.html" title="interface in jakarta.enterprise.concurrent"><code>ManagedExecutorService</code></a> or <a href="../../../jakarta/enterprise/concurrent/ManagedScheduledExecutorService.html" title="interface in jakarta.enterprise.concurrent"><code>ManagedScheduledExecutorService</code></a>
upon which to run the asynchronous method.</div>
</td>
</tr>
</table>
</li>
</ul>
</li>
</ul>
</div>
<div class="details">
<ul class="blockList">
<li class="blockList">
<!-- ============ ANNOTATION TYPE MEMBER DETAIL =========== -->
<ul class="blockList">
<li class="blockList"><a name="annotation.type.element.detail">
<!-- -->
</a>
<h3>Element Detail</h3>
<a name="executor--">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>executor</h4>
<pre>public abstract&nbsp;java.lang.String&nbsp;executor</pre>
<div class="block">JNDI name of a <a href="../../../jakarta/enterprise/concurrent/ManagedExecutorService.html" title="interface in jakarta.enterprise.concurrent"><code>ManagedExecutorService</code></a> or <a href="../../../jakarta/enterprise/concurrent/ManagedScheduledExecutorService.html" title="interface in jakarta.enterprise.concurrent"><code>ManagedScheduledExecutorService</code></a>
upon which to run the asynchronous method.
<p>
The default value is the JNDI name of the built-in <code>ManagedExecutorService</code>
that is provided by the Jakarta EE platform provider:<br>
<code>java:comp/DefaultManagedExecutorService</code></div>
<dl>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>managed executor service JNDI name.</dd>
</dl>
<dl>
<dt>Default:</dt>
<dd>"java:comp/DefaultManagedExecutorService"</dd>
</dl>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- ========= END OF CLASS DATA ========= -->
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar.bottom">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.bottom" title="Skip navigation links">Skip navigation links</a></div>
<a name="navbar.bottom.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../overview-summary.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../index-all.html">Index</a></li>
<li><a href="../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="../../../jakarta/enterprise/concurrent/AbortedException.html" title="class in jakarta.enterprise.concurrent"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
<li><a href="../../../jakarta/enterprise/concurrent/Asynchronous.Result.html" title="class in jakarta.enterprise.concurrent"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
</ul>
<ul class="navList">
<li><a href="../../../index.html?jakarta/enterprise/concurrent/Asynchronous.html" target="_top">Frames</a></li>
<li><a href="Asynchronous.html" target="_top">No&nbsp;Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<div>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li>Required&nbsp;|&nbsp;</li>
<li><a href="#annotation.type.optional.element.summary">Optional</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#annotation.type.element.detail">Element</a></li>
</ul>
</div>
<a name="skip.navbar.bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>