<div dir="ltr"><div><div>Hi,<br><br></div>I&#39;m attempting to emulate EJB&#39;s @Asynchronous in CDI using interceptors.<br><br>Originally I had defined my interceptor as follows;<br><br>@Interceptor<br>@Asynchronous<br>@Priority(APPLICATION)<br>public class AsynchronousInterceptor implements Serializable {<br><br>    private static final long serialVersionUID = 1L;<br>    <br>    @Resource<br>    private ManagedExecutorService managedExecutorService;<br><br>    @AroundInvoke<br>    public Object submitAsync(InvocationContext ctx) throws Exception {<br>        return new FutureDelegator(managedExecutorService.submit( ()-&gt; { return ctx.proceed(); } ));<br>    }<br><br>}<br><br></div><div>With FutureDelegator as follows:<br><br>public class FutureDelegator implements Future&lt;Object&gt; {<br>    <br>    private Future&lt;?&gt; future;<br>    <br>    public FutureDelegator(Future&lt;?&gt; future) {<br>        this.future = future;<br>    }<br><br>    @Override<br>    public Object get() throws InterruptedException, ExecutionException {<br>        AsyncResult&lt;?&gt; asyncResult = (AsyncResult&lt;?&gt;) future.get();<br>        if (asyncResult == null) {<br>            return null;<br>        }<br>        <br>        return asyncResult.get(); <br>    }<br>    <br>    @Override<br>    public Object get(long timeout, TimeUnit unit) throws InterruptedException,    ExecutionException, TimeoutException {<br>        AsyncResult&lt;?&gt; asyncResult = (AsyncResult&lt;?&gt;) future.get(timeout, unit);<br>        if (asyncResult == null) {<br>            return null;<br>        }<br>        <br>        return asyncResult.get(); <br>    }<br>    <br>    @Override<br>    public boolean cancel(boolean mayInterruptIfRunning) {<br>        return future.cancel(mayInterruptIfRunning);<br>    }<br>    <br>    @Override<br>    public boolean isCancelled() {<br>        return future.isCancelled();<br>    }<br>    @Override<br>    public boolean isDone() {<br>        return future.isDone();<br>    }<br>    <br>}<br><br></div><div>This of course didn&#39;t quite work, as the InvocationContext will be reset after the @AroundInvoke method returns, and an infinite intercept loop results (on Weld).<br><br>I got it to work though on Weld by using a thread local check to break that loop:<br><br>@Interceptor<br>@Asynchronous<br>@Priority(PLATFORM_BEFORE)<br>public class AsynchronousInterceptor implements Serializable {<br><br>    private static final long serialVersionUID = 1L;<br>    <br>    @Resource<br>    private ManagedExecutorService managedExecutorService;<br>    <br>    private static final ThreadLocal&lt;Boolean&gt; asyncInvocation = new ThreadLocal&lt;Boolean&gt;();<br><br>    @AroundInvoke<br>    public synchronized Object submitAsync(InvocationContext ctx) throws Exception {<br>        <br>        if (TRUE.equals(asyncInvocation.get())) {<br>            return ctx.proceed();<br>        }<br>        <br>        return new FutureDelegator(managedExecutorService.submit( ()-&gt; { <br>            try {<br>                asyncInvocation.set(TRUE);<br>                return ctx.proceed();<br>            } finally {<br>                 asyncInvocation.remove();<br>            }<br>        }));<br>    }<br><br>}<br><br></div><div>But I&#39;ve got a feeling this works just by chance and not because the workaround is so clever.<br><br></div><div>What do you guys think, what would be the best way to support this with the current CDI version? Or would CDI/Interceptors need something like Servlet&#39;s async support, where the InvocationContext is put into async mode whereafter it &quot;simply&quot; allows an other thread to continue processing on it?<br><br></div><div>Kind regards,<br>Arjan Tijms<br></div><div><br></div><div><br></div><div><br></div><div><br><br></div></div>