Top Description Inners Methods
jakarta.enterprise.concurrent

public @Interface Asynchronous

extends Annotation
Annotations
@Documented
@Inherited
@InterceptorBinding
@Retention:RUNTIME
@Target:METHOD, TYPE
Imports
java.lang.annotation.Documented, .ElementType, .Inherited, .Retention, .RetentionPolicy, .Target, java.util.concurrent.CompletableFuture, jakarta.enterprise.util.Nonbinding, jakarta.interceptor.InterceptorBinding

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 a CompletableFuture that is backed by the same ManagedExecutorService to represent the execution of the method. The ManagedExecutorService is the default asynchronous execution facility for the CompletableFuture and and all dependent stages that are created from those, and so on, as defined by the ManagedExecutorService JavaDoc API. The Jakarta EE Product Provider makes this CompletableFuture available to the asynchronous method implementation via the Asynchronous.Result.getFuture and Asynchronous.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 different CompletableFuture instance, the Jakarta EE Product Provider uses the completion of that instance to complete the CompletableFuture 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 of ElementType.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 resulting CompletableFuture either by raising a CompletionException with the original exception as the cause, or it can take the equivalent approach of exceptionally completing the CompletableFuture, using completeExceptionally 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 the CompletableFuture exceptionally with CancellationException, 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 as Transactional, must run on the thread where the asynchronous method executes, rather than on the submitting thread. When an asynchronous method is annotated as Transactional, the transactional types which can be used are: TxType.REQUIRES_NEW, which causes the method to run in a new transaction, and TxType.NOT_SUPPORTED, which causes the method to run with no transaction. All other transaction attributes must result in UnsupportedOperationException upon invocation of the asynchronous method.

Since
3.0

Nested and Inner Type Summary

Modifier and TypeClass and Description
public static class
Asynchronous.Result

Mechanism by which the Jakarta EE Product Provider makes available to the asynchronous method implementation the same CompletableFuture instance that the Jakarta EE Product Provider supplies to the caller of the asynchronous method.

Method Summary

Modifier and TypeMethod and Description
public String

Returns:

managed executor service JNDI name.
executor
()

JNDI name of a ManagedExecutorService or ManagedScheduledExecutorService upon which to run the asynchronous method.

public Schedule[]

Returns:

a schedule for the task or an empty array, where the latter indicates to run once without a schedule.
runAt
()

Establishes a schedule for repeated execution of the method.

Inherited from java.lang.annotation.Annotation:
annotationTypeequalshashCodetoString

Method Detail

executorback to summary
public String executor()

JNDI name of a ManagedExecutorService or ManagedScheduledExecutorService 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:String

managed executor service JNDI name.

Annotations
@Nonbinding
runAtback to summary
public Schedule[] runAt()

Establishes a schedule for repeated execution of the method. A single future represents the completion of all executions in the schedule. The Jakarta EE product attempts to run the method at the scheduled times until its future is completed or the method returns a non-null result value or raises an exception. The future is always accessible from within the method via Asynchronous.Result which returns a typed CompletableFuture which matches the return type of the method. If the method return type is void then Asynchronous.Result will return a CompletableFuture<Void>.

Computation of the start time for the next execution occurs after the completion of the current execution. This prevents overlap of executions from the same asynchronous method request. Scheduled execution times that overlap a prior execution that is still running are skipped. For example, if an asynchronous method is scheduled to run every minute on the minute and execution of the method starts at 8:00 AM, lasting for 2 minutes and 10 seconds, then the Jakarta EE product attempts to start the next execution of the method at 8:03 AM.

Scheduled asynchronous methods are treated similar to other scheduled tasks in that they are not subject to max-async constraints of managed-scheduled-executor-definition and managed-executor-definition and the corresponding ManagedScheduledExecutorDefinition#maxAsync() and ManagedExecutorDefinition#maxAsync().

When a list of multiple Schedule annotations is specified, the next execution time is computed according to each, choosing the closest future time after the current time. This allows composite schedules such as,

@Asynchronous(runAt = {
    @Schedule(daysOfWeek = { DayOfWeek.TUESDAY, DayOfWeek.THURSDAY }, hours = 8),
    @Schedule(daysOfweek = DayOfWeek.WEDNESDAY, hours = 10, minutes = 30)
})
public CompletableFuture<String> attendLectureAndLab(String course) {
    ...
    if (endOfSemester)
        return Asynchronous.Result.complete(courseRecord);
    else
        return null; // continue at next scheduled time
}

...

student.attendLectureAndLab(courseName).thenApply(this::assignGrade);

The default value of empty array indicates that the task does not run on a schedule and instead runs one time.

Returns:Schedule[]

a schedule for the task or an empty array, where the latter indicates to run once without a schedule.

Annotations
@Nonbinding
jakarta.enterprise.concurrent back to summary

public final Class Asynchronous.Result

extends Object
Class Inheritance

Mechanism by which the Jakarta EE Product Provider makes available to the asynchronous method implementation the same CompletableFuture instance that the Jakarta EE Product Provider supplies to the caller of the asynchronous method.

Before invoking the asynchronous method implementation on a thread, the Jakarta EE Product Provider invokes the setFuture method which makes available to the asynchronous method implementation the same CompletableFuture that the Jakarta EE Product Provider returns to the caller.

The asynchronous method implementation invokes the getFuture method to obtain the same CompletableFuture that the Jakarta EE Product Provider returns to the caller. The asynchronous method implementation can choose to complete this future (normally or exceptionally) or otherwise arrange for its completion, for example upon completion of a pipeline of completion stages. Having this same CompletableFuture also enables the asynchronous method implementation to determine if the caller has forcibly completed (such as by cancellation or any other means) the CompletableFuture, in which case the asynchronous method implementation could decide to end immediately rather than continue processing.

For example,

@Asynchronous
public CompletableFuture<Double> hoursWorked(LocalDateTime from, LocalDateTime to) {
    CompletableFuture<Double> future = Asynchronous.Result.getFuture();
    if (future.isDone())
        return future;

    try (Connection con = ((DataSource) InitialContext.doLookup(
        "java:comp/env/jdbc/timesheetDB")).getConnection()) {
        ...
        for (ResultSet result = stmt.executeQuery(); result.next() && !future.isDone(); )
            ...
        future.complete(total);
    } catch (NamingException | SQLException x) {
        future.completeExceptionally(x);
    }
    return future;
}
After the asynchronous method completes, the Jakarta EE Product Provider invokes the setFuture method with a null value to clear it from the thread.
Since
3.0

Field Summary

Modifier and TypeField and Description
private static final ThreadLocal<CompletableFuture<?>>

Constructor Summary

AccessConstructor and Description
private

Method Summary

Modifier and TypeMethod and Description
public static <
type of result returned by the asynchronous method's CompletableFuture.
T
>
CompletableFuture<T>

Returns:

the same CompletableFuture that the container returns to the caller.
complete
(final T
result with which to complete the asynchronous method's CompletableFuture.
result
)

Completes the CompletableFuture instance that the Jakarta EE Product Provider supplies to the caller of the asynchronous method.

public static <
type of result returned by the asynchronous method's CompletableFuture.
T
>
CompletableFuture<T>

Returns:

the same CompletableFuture that the container returns to the caller.
getFuture
()

Obtains the same CompletableFuture instance that the Jakarta EE Product Provider supplies to the caller of the asynchronous method.

public static <
type of result returned by the asynchronous method's CompletableFuture.
T
>
void
setFuture(final CompletableFuture<T>
CompletableFuture that the container returns to the caller, or null to clear it.
future
)

Before invoking the asynchronous method implementation on a thread, the Jakarta EE Product Provider invokes this method to make available to the asynchronous method implementation the same CompletableFuture that the Jakarta EE Product Provider returns to the caller.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

FUTURESback to summary
private static final ThreadLocal<CompletableFuture<?>> FUTURES

Constructor Detail

Resultback to summary
private Result()

Method Detail

completeback to summary
public static <T> CompletableFuture<T> complete(final T result)

Completes the CompletableFuture instance that the Jakarta EE Product Provider supplies to the caller of the asynchronous method.

This method must only be invoked by the asynchronous method implementation.

Parameters
<T>
type of result returned by the asynchronous method's CompletableFuture.
result:T

result with which to complete the asynchronous method's CompletableFuture.

Returns:CompletableFuture<T>

the same CompletableFuture that the container returns to the caller.

Exceptions
IllegalStateException:
if the CompletableFuture for an asynchronous method is not present on the thread.
getFutureback to summary
public static <T> CompletableFuture<T> getFuture()

Obtains the same CompletableFuture instance that the Jakarta EE Product Provider supplies to the caller of the asynchronous method.

This method must only be invoked by the asynchronous method implementation.

Parameters
<T>
type of result returned by the asynchronous method's CompletableFuture.
Returns:CompletableFuture<T>

the same CompletableFuture that the container returns to the caller.

Exceptions
IllegalStateException:
if the CompletableFuture for an asynchronous method is not present on the thread.
setFutureback to summary
public static <T> void setFuture(final CompletableFuture<T> future)

Before invoking the asynchronous method implementation on a thread, the Jakarta EE Product Provider invokes this method to make available to the asynchronous method implementation the same CompletableFuture that the Jakarta EE Product Provider returns to the caller.

After the asynchronous method completes, the Jakarta EE Product Provider invokes this method with a null value to clear it from the thread.

This method must only be invoked by the Jakarta EE Product Provider.

Parameters
<T>
type of result returned by the asynchronous method's CompletableFuture.
future:CompletableFuture<T>

CompletableFuture that the container returns to the caller, or null to clear it.