diff --git a/api/src/main/java/jakarta/enterprise/concurrent/Async.java b/api/src/main/java/jakarta/enterprise/concurrent/Async.java index 001c00e1..c4d1ac7a 100644 --- a/api/src/main/java/jakarta/enterprise/concurrent/Async.java +++ b/api/src/main/java/jakarta/enterprise/concurrent/Async.java @@ -28,8 +28,7 @@ import jakarta.interceptor.InterceptorBinding; /** - * Annotates a CDI managed bean method (or CDI managed bean class containing suitable methods) - * to run asynchronously. + * Annotates a CDI managed bean method to run asynchronously. *

* The Jakarta EE Product Provider runs the method on a {@link ManagedExecutorService} * and returns to the caller a {@link java.util.concurrent.CompletableFuture CompletableFuture} @@ -101,26 +100,21 @@ * * *

- * When annotating asynchronous methods at the method level, methods - * can have any of the following return types, with all other return types resulting in - * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}: + * Methods with the following return types can be annotated to be + * asynchronous methods: *

*

- * When annotating asynchronous methods at the class level, methods with - * any of the following return types are considered asynchronous methods, - * whereas methods with other return types are treated as normal - * (non-asynchronous) methods: - *

- *

- * If the Async annotation is present at both the method and class - * level, the annotation that is specified at the method level takes precedence. + * The Jakarta EE Product Provider raises + * {@link java.lang.UnsupportedOperationException 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. @@ -152,9 +146,11 @@ * 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 TxType.REQUIRES_NEW and - * TxType.NOT_SUPPORTED can be used. All other transaction attributes must - * result in {@link java.lang.UnsupportedOperationException UnsupportedOperationException} + * 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 + * {@link java.lang.UnsupportedOperationException UnsupportedOperationException} * upon invocation of the asynchronous method. * * @since 3.0 diff --git a/api/src/test/java/jakarta/enterprise/concurrent/AsyncTest.java b/api/src/test/java/jakarta/enterprise/concurrent/AsyncTest.java index 143d3b15..764d8a5c 100644 --- a/api/src/test/java/jakarta/enterprise/concurrent/AsyncTest.java +++ b/api/src/test/java/jakarta/enterprise/concurrent/AsyncTest.java @@ -43,7 +43,6 @@ * for asychronous methods, verifying that they compile. * The Async.Result class is also tested. */ -@Async(executor = "java:module/env/concurrent/class-level-async-executor") public class AsyncTest { /** * Example from the section on Asynchronous Methods in the Concurrency spec. @@ -195,17 +194,6 @@ List flightsTo() { } } - /** - * Verify that the Async annotation can be configured at class level - * and that its executor field is populated with the specified value. - */ - @Test - public void testAsyncClassLevelAnnotation() throws Exception { - Async anno = AsyncTest.class.getAnnotation(Async.class); - assertNotNull(anno); - assertEquals("java:module/env/concurrent/class-level-async-executor", anno.executor()); - } - /** * Verify that the first usage example in the Async class JavaDoc compiles. */ diff --git a/specification/src/main/asciidoc/jakarta-concurrency.adoc b/specification/src/main/asciidoc/jakarta-concurrency.adoc index 196aa3a0..57d843e7 100644 --- a/specification/src/main/asciidoc/jakarta-concurrency.adoc +++ b/specification/src/main/asciidoc/jakarta-concurrency.adoc @@ -2306,8 +2306,7 @@ task. == Asynchronous Methods The `jakarta.enterprise.concurrent.Async` annotation annotates a -CDI managed bean method to run asynchronously or annotates a -CDI managed bean class with methods to run asynchronously. +CDI managed bean method to run asynchronously. Each asynchronous method execution corresponds to a managed `java.util.concurrent.CompletableFuture` instance that is backed by a @@ -2327,11 +2326,7 @@ specify the `jakarta.enterprise.concurrent.Async` annotation on CDI managed bean methods with return type of `java.util.concurrent.CompletableFuture`, `java.util.concurrent.CompletionStage`, or `void` to designate them for -asynchronous execution. Alternatively, the -`jakarta.enterprise.concurrent.Async` annotation can be specified on a -CDI managed bean class to designate all methods with return type of -`java.util.concurrent.CompletableFuture` or -`java.util.concurrent.CompletionStage` for asynchronous execution. +asynchronous execution. The Application Component Provider supplies the implementation of the asynchronous method. If the method has return type of @@ -2443,10 +2438,18 @@ for any reason after this point, it completes the ==== Transaction Management -Asynchronous method can be annotated with -`jakarta.transaction.Transactional` types of -`jakarta.transaction.Transactional.TxType.REQUIRES_NEW` or -`jakarta.transaction.Transactional.TxType.NOT_SUPPORTED`. +When an asynchronous method is also annotated with +`jakarta.transaction.Transactional`, the transactional types which can be +used are: + +* `jakarta.transaction.Transactional.TxType.REQUIRES_NEW` - +which causes the method to run in a new transaction +* `jakarta.transaction.Transactional.TxType.NOT_SUPPORTED` - +which causes the method to run with no transaction + +All other transaction attributes must result in +`java.lang.UnsupportedOperationException` upon invocation of the +asynchronous method. When an asynchronous method is not annotated as `jakarta.transaction.Transactional` or the transaction type is set to