This is an automated email from the ASF dual-hosted git repository.
rzo1 pushed a commit to branch concurency
in repository https://gitbox.apache.org/repos/asf/tomee.git
The following commit(s) were added to refs/heads/concurency by this push:
new b4dc7bfe3c Support plain ManagedExecutorService as executor for
scheduled async
b4dc7bfe3c is described below
commit b4dc7bfe3c1a517e56398ad22839b29e1443dd75
Author: Richard Zowalla <[email protected]>
AuthorDate: Thu Apr 2 16:22:27 2026 +0200
Support plain ManagedExecutorService as executor for scheduled async
Per spec, @Asynchronous(executor=..., runAt=@Schedule(...)) may reference
a plain ManagedExecutorService, not just a ManagedScheduledExecutorService.
When MSES lookup fails, verify the executor exists as MES and fall back to
the default MSES for scheduling capability.
---
.../cdi/concurrency/AsynchronousInterceptor.java | 16 ++++++++++--
.../AsynchronousScheduledTCKStyleTest.java | 29 ++++++++++++++++++++++
2 files changed, 43 insertions(+), 2 deletions(-)
diff --git
a/container/openejb-core/src/main/java/org/apache/openejb/cdi/concurrency/AsynchronousInterceptor.java
b/container/openejb-core/src/main/java/org/apache/openejb/cdi/concurrency/AsynchronousInterceptor.java
index 7a2387f4e6..01569d9b5d 100644
---
a/container/openejb-core/src/main/java/org/apache/openejb/cdi/concurrency/AsynchronousInterceptor.java
+++
b/container/openejb-core/src/main/java/org/apache/openejb/cdi/concurrency/AsynchronousInterceptor.java
@@ -111,11 +111,23 @@ public class AsynchronousInterceptor {
private Object aroundInvokeScheduled(final InvocationContext ctx, final
Asynchronous asynchronous,
final Schedule[] schedules) throws
Exception {
- final ManagedScheduledExecutorService mses;
+ // Per spec, the executor attribute may reference either a
ManagedScheduledExecutorService
+ // or a plain ManagedExecutorService. When a plain MES is referenced,
fall back to the
+ // default MSES for scheduling capability (the trigger mechanism
requires MSES).
+ ManagedScheduledExecutorService mses;
try {
mses =
ManagedScheduledExecutorServiceImplFactory.lookup(asynchronous.executor());
} catch (final IllegalArgumentException e) {
- throw new RejectedExecutionException("Cannot lookup
ManagedScheduledExecutorService", e);
+ // The executor might be a plain ManagedExecutorService — verify
it exists,
+ // then use the default MSES for scheduling
+ try {
+
ManagedExecutorServiceImplFactory.lookup(asynchronous.executor());
+ // MES exists — use default MSES for scheduling
+ mses = ManagedScheduledExecutorServiceImplFactory.lookup(
+ "java:comp/DefaultManagedScheduledExecutorService");
+ } catch (final Exception fallbackEx) {
+ throw new RejectedExecutionException("Cannot lookup executor
for scheduled async method", e);
+ }
}
final ZonedTrigger trigger = ScheduleHelper.toTrigger(schedules);
diff --git
a/container/openejb-core/src/test/java/org/apache/openejb/cdi/concurrency/AsynchronousScheduledTCKStyleTest.java
b/container/openejb-core/src/test/java/org/apache/openejb/cdi/concurrency/AsynchronousScheduledTCKStyleTest.java
index b6a5f7555e..49825855f3 100644
---
a/container/openejb-core/src/test/java/org/apache/openejb/cdi/concurrency/AsynchronousScheduledTCKStyleTest.java
+++
b/container/openejb-core/src/test/java/org/apache/openejb/cdi/concurrency/AsynchronousScheduledTCKStyleTest.java
@@ -195,6 +195,23 @@ public class AsynchronousScheduledTCKStyleTest {
assertEquals(Integer.valueOf(3), result2);
}
+ /**
+ * TCK: testScheduledAsynchIgnoresMaxAsync (MED-Web variant)
+ * Method with @Asynchronous(executor=MES, runAt=@Schedule) — the executor
is a plain
+ * ManagedExecutorService, not a ManagedScheduledExecutorService. The
interceptor
+ * should fall back to the default MSES for scheduling.
+ */
+ @Test
+ public void scheduledWithManagedExecutorServiceExecutor() throws Exception
{
+ final AtomicInteger counter = new AtomicInteger();
+ // This method references the default MES (not MSES) as executor
+ final CompletableFuture<Integer> future =
reqBean.scheduledWithMESExecutor(2, counter);
+
+ assertNotNull("Future should be returned even when executor is MES",
future);
+ final Integer result = future.get(15, TimeUnit.SECONDS);
+ assertEquals("Should complete after 2 runs", Integer.valueOf(2),
result);
+ }
+
// --- Bean ---
public enum ReturnType {
@@ -257,6 +274,18 @@ public class AsynchronousScheduledTCKStyleTest {
return future;
}
+ @Asynchronous(executor = "java:comp/DefaultManagedExecutorService",
+ runAt = @Schedule(cron = "* * * * * *"))
+ public CompletableFuture<Integer> scheduledWithMESExecutor(final int
runs, final AtomicInteger counter) {
+ final int count = counter.incrementAndGet();
+ if (count < runs) {
+ return null;
+ }
+ final CompletableFuture<Integer> future =
Asynchronous.Result.getFuture();
+ future.complete(count);
+ return future;
+ }
+
@Asynchronous(executor = "java:comp/env/invalid/executor",
runAt = @Schedule(cron = "* * * * * *"))
public CompletableFuture<String> scheduledInvalidExecutor() {