-
@Documented @Inherited @InterceptorBinding @Retention(RUNTIME) @Target({METHOD,TYPE}) public @interface Asynchronous
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.The Jakarta EE Product Provider runs the method on a
ManagedExecutorService
and returns to the caller aCompletableFuture
that is backed by the sameManagedExecutorService
to represent the execution of the method. TheManagedExecutorService
is the default asynchronous execution facility for theCompletableFuture
and and all dependent stages that are created from those, and so on, as defined by theManagedExecutorService
JavaDoc API. The Jakarta EE Product Provider makes thisCompletableFuture
available to the asynchronous method implementation via theAsynchronous.Result.getFuture
andAsynchronous.Result.complete
methods.For example,
@Asynchronous public CompletableFuture<Double> 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); } }
with usage,hoursWorked(mon, fri).thenAccept(total -> { // Application component's context is made available to dependent stage actions, DataSource ds = InitialContext.doLookup( "java:comp/env/jdbc/payrollDB"); ... });
When the asynchronous method implementation returns a differentCompletableFuture
instance, the Jakarta EE Product Provider uses the completion of that instance to complete theCompletableFuture
that the Jakarta EE Product Provider returns to the caller, completing it with the same result or exception.For example,
@Asynchronous public CompletableFuture<List<Itinerary>> 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); } }
with usage,findSingleLayoverFlights(RST, DEN).thenApply(Itinerary::sortByPrice);
Methods with the following return types can be annotated to be asynchronous methods:
The Jakarta EE Product Provider raises
UnsupportedOperationException
if other return types are used or if the annotation is placed at the class level. The injection target ofElementType.TYPE
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.Exceptions that are raised by asynchronous methods are not raised directly to the caller because the method runs asynchronously to the caller. Instead, the
CompletableFuture
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 resultingCompletableFuture
either by raising aCompletionException
with the original exception as the cause, or it can take the equivalent approach of exceptionally completing theCompletableFuture
, usingcompleteExceptionally
to supply the original exception as the cause.Except where otherwise stated, the Jakarta EE Product Provider raises
RejectedExecutionException
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 theCompletableFuture
exceptionally withCancellationException
, and chains a cause exception if there is any.The Jakarta EE Product Provider must assign the interceptor for asynchronous methods to have priority of
Interceptor.Priority.PLATFORM_BEFORE + 5
. Interceptors with a lower priority, such asTransactional
, must run on the thread where the asynchronous method executes, rather than on the submitting thread. When an asynchronous method is annotated asTransactional
, the transactional types which can be used are:TxType.REQUIRES_NEW
, which causes the method to run in a new transaction, andTxType.NOT_SUPPORTED
, which causes the method to run with no transaction. All other transaction attributes must result inUnsupportedOperationException
upon invocation of the asynchronous method.- Since:
- 3.0
-
-
Optional Element Summary
Optional Elements Modifier and Type Optional Element Description String
executor
JNDI name of aManagedExecutorService
orManagedScheduledExecutorService
upon which to run the asynchronous method.
-
-
-
Element Detail
-
executor
String executor
JNDI name of aManagedExecutorService
orManagedScheduledExecutorService
upon which to run the asynchronous method.The default value is the JNDI name of the built-in
ManagedExecutorService
that is provided by the Jakarta EE platform provider:
java:comp/DefaultManagedExecutorService
- Returns:
- managed executor service JNDI name.
- Default:
- "java:comp/DefaultManagedExecutorService"
-
-