<div dir="ltr">@Arjan, remember the email I sent to the EE EG entitled &quot;Status of the Java EE 8 specifications&quot;. Bill Shannon replied : <div><br></div><div><i>We agree on the long term vision.  This is almost entirely a <b>resource issue</b>.  In order to do this, we have to stop doing something else, or we have to delay the release.  Based on the feedback we&#39;ve gotten from the community, the things we&#39;ve chosen to work on right now are the most important.  We&#39;d like to do what you suggest below as well, but it&#39;s most likely going to have to be done later.</i><br></div><div><br></div><div>So I don&#39;t know how we could &quot;push&quot; for an MR of the EE Concurrency spec. Any idea ? Except harassing Bill to add resources to the EE Concurrency spec and taking other resources out somewhere else... I don&#39;t know how we could do this.</div><div><br></div><div>@Mark EE Concurreny could also add a @ThreadScoped like the one in Weld (but with a EE meaning).</div><div><br></div><div>Antonio</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Jan 17, 2015 at 1:53 PM, Mark Struberg <span dir="ltr">&lt;<a href="mailto:struberg@yahoo.de" target="_blank">struberg@yahoo.de</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">EE concurrency spec needs an update anyway. It currently doesn&#39;t explicitly require @RequestScoped beans to be supported on a new Thread. That breaks tons of frameworks and makes it barely usable in EE7.<br>
<br>
LieGrue,<br>
strub<br>
<div class="HOEnZb"><div class="h5"><br>
On Saturday, 17 January 2015, 13:12, arjan tijms &lt;<a href="mailto:arjan.tijms@gmail.com">arjan.tijms@gmail.com</a>&gt; wrote:<br>
<br>
<br>
&gt;<br>
&gt;<br>
&gt;Hi,<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;On Sat, Jan 17, 2015 at 11:05 AM, Antonio Goncalves &lt;<a href="mailto:antonio.goncalves@gmail.com">antonio.goncalves@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt;@arjan Your example is base on  ManagedExecutorService from the Java EE Concurrency spec. That&#39;s one topic we&#39;ve been wondering about : should the @Asynchronous interceptor go to the Java EE Concurrency spec or not ? But it looks like the spec might not be updated.<br>
&gt;<br>
&gt;<br>
&gt;The example I showed here would IMHO best be placed in the Java EE Concurrency spec. That would in my opinion be a perfect analogy to @Transactional and JTA. As given, the interceptor uses CDI/Interceptors and Concurrency, so theoretically it could also be put into a third spec.<br>
&gt;<br>
&gt;<br>
&gt;Personally I would find it strange to put something in spec A, when it may better belong in spec B, just because spec B is not updated. What&#39;s holding the update of Java EE Concurrency back? If most of the EG members would be of the opinion that an @Asynchronous interceptor belongs best in Java EE Concurrency, then we can just update that spec, right?<br>
&gt;<br>
&gt;<br>
&gt;I know that MR releases can be quite fast and agile process wise, while still packing some punch. JTA 1.2 itself was just such an MR, and JASPIC 1.1 was too. I was somewhat involved with JASPIC 1.1 (as community member) and I think the setup time was pretty fast. Mid feb 2013 we created the JIRA issues, the MR draft was published early march 2013 and the release was with EE 7 end may 2013.<br>
&gt;<br>
&gt;<br>
&gt;If it would just be about putting a few interceptors formally in Java EE Concurrency, then why not do such small update for it?<br>
&gt;<br>
&gt;<br>
&gt;Kind regards,<br>
&gt;Arjan<br>
&gt;<br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt;Antonio<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;On Sat, Jan 17, 2015 at 12:32 AM, arjan tijms &lt;<a href="mailto:arjan.tijms@gmail.com">arjan.tijms@gmail.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt;Hi,<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;On Fri, Jan 16, 2015 at 10:41 PM, Jozef Hartinger &lt;<a href="mailto:jharting@redhat.com">jharting@redhat.com</a>&gt; wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;Hi Arjan,<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;I did some changes recently in Weld interceptors and this usecase<br>
    now works smoothly. The code is not part of a release yet. See this<br>
    test for a simple implementation of an @Async interceptor (basically<br>
    the same as your initial attempt). Note that the chain is repeatable<br>
    but at the same time it is not reset after dispatch to a different<br>
    thread so you no longer need the ThreadLocal nor any other<br>
    workaround.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;That&#39;s quite a coincidence, it&#39;s indeed rather similar ;)<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;I wonder how it now works though, as the InvocationContext &quot;ctx&quot; does not seem to be made aware that it&#39;s been dispatched to a different thread from within the code. Does it use an internal thread local to keep state or so?<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;I&#39;ll also try to see what this does on OWB. Do you think this is something that should work, or just something that Weld happens to support regardless of the spec?<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;Kind regards,<br>
&gt;&gt;&gt;Arjan<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;<a href="https://github.com/weld/core/blob/master/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/thread/async/AsyncInterceptor.java" target="_blank">https://github.com/weld/core/blob/master/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/thread/async/AsyncInterceptor.java</a><br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;Jozef<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;On 01/16/2015 06:17 PM, arjan tijms wrote:<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;Hi,<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
I&#39;m attempting to emulate EJB&#39;s @Asynchronous in CDI using interceptors.<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;Originally I had defined my interceptor as follows;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;@Interceptor<br>
&gt;&gt;&gt;&gt;&gt;@Asynchronous<br>
&gt;&gt;&gt;&gt;&gt;@Priority(APPLICATION)<br>
&gt;&gt;&gt;&gt;&gt;public class AsynchronousInterceptor implements Serializable {<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;    private static final long serialVersionUID = 1L;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;    @Resource<br>
&gt;&gt;&gt;&gt;&gt;    private ManagedExecutorService managedExecutorService;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;    @AroundInvoke<br>
&gt;&gt;&gt;&gt;&gt;    public Object submitAsync(InvocationContext ctx) throws<br>
          Exception {<br>
&gt;&gt;&gt;&gt;&gt;        return new<br>
          FutureDelegator(managedExecutorService.submit( ()-&gt; {<br>
          return ctx.proceed(); } ));<br>
&gt;&gt;&gt;&gt;&gt;    }<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;}<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;With FutureDelegator as follows:<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;public class FutureDelegator implements Future&lt;Object&gt; {<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;    private Future&lt;?&gt; future;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;    public FutureDelegator(Future&lt;?&gt; future) {<br>
&gt;&gt;&gt;&gt;&gt;        this.future = future;<br>
&gt;&gt;&gt;&gt;&gt;    }<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;    @Override<br>
&gt;&gt;&gt;&gt;&gt;    public Object get() throws InterruptedException,<br>
          ExecutionException {<br>
&gt;&gt;&gt;&gt;&gt;        AsyncResult&lt;?&gt; asyncResult =<br>
          (AsyncResult&lt;?&gt;) future.get();<br>
&gt;&gt;&gt;&gt;&gt;        if (asyncResult == null) {<br>
&gt;&gt;&gt;&gt;&gt;            return null;<br>
&gt;&gt;&gt;&gt;&gt;        }<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;        return asyncResult.get();<br>
&gt;&gt;&gt;&gt;&gt;    }<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;    @Override<br>
&gt;&gt;&gt;&gt;&gt;    public Object get(long timeout, TimeUnit unit) throws<br>
          InterruptedException,    ExecutionException, TimeoutException<br>
          {<br>
&gt;&gt;&gt;&gt;&gt;        AsyncResult&lt;?&gt; asyncResult =<br>
          (AsyncResult&lt;?&gt;) future.get(timeout, unit);<br>
&gt;&gt;&gt;&gt;&gt;        if (asyncResult == null) {<br>
&gt;&gt;&gt;&gt;&gt;            return null;<br>
&gt;&gt;&gt;&gt;&gt;        }<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;        return asyncResult.get();<br>
&gt;&gt;&gt;&gt;&gt;    }<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;    @Override<br>
&gt;&gt;&gt;&gt;&gt;    public boolean cancel(boolean mayInterruptIfRunning) {<br>
&gt;&gt;&gt;&gt;&gt;        return future.cancel(mayInterruptIfRunning);<br>
&gt;&gt;&gt;&gt;&gt;    }<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;    @Override<br>
&gt;&gt;&gt;&gt;&gt;    public boolean isCancelled() {<br>
&gt;&gt;&gt;&gt;&gt;        return future.isCancelled();<br>
&gt;&gt;&gt;&gt;&gt;    }<br>
&gt;&gt;&gt;&gt;&gt;    @Override<br>
&gt;&gt;&gt;&gt;&gt;    public boolean isDone() {<br>
&gt;&gt;&gt;&gt;&gt;        return future.isDone();<br>
&gt;&gt;&gt;&gt;&gt;    }<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;}<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;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>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;I got it to work though on Weld by using a thread local check<br>
          to break that loop:<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;@Interceptor<br>
&gt;&gt;&gt;&gt;&gt;@Asynchronous<br>
&gt;&gt;&gt;&gt;&gt;@Priority(PLATFORM_BEFORE)<br>
&gt;&gt;&gt;&gt;&gt;public class AsynchronousInterceptor implements Serializable {<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;    private static final long serialVersionUID = 1L;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;    @Resource<br>
&gt;&gt;&gt;&gt;&gt;    private ManagedExecutorService managedExecutorService;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;    private static final ThreadLocal&lt;Boolean&gt;<br>
          asyncInvocation = new ThreadLocal&lt;Boolean&gt;();<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;    @AroundInvoke<br>
&gt;&gt;&gt;&gt;&gt;    public synchronized Object submitAsync(InvocationContext<br>
          ctx) throws Exception {<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;        if (TRUE.equals(asyncInvocation.get())) {<br>
&gt;&gt;&gt;&gt;&gt;            return ctx.proceed();<br>
&gt;&gt;&gt;&gt;&gt;        }<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;        return new<br>
          FutureDelegator(managedExecutorService.submit( ()-&gt; {<br>
&gt;&gt;&gt;&gt;&gt;            try {<br>
&gt;&gt;&gt;&gt;&gt;                asyncInvocation.set(TRUE);<br>
&gt;&gt;&gt;&gt;&gt;                return ctx.proceed();<br>
&gt;&gt;&gt;&gt;&gt;            } finally {<br>
&gt;&gt;&gt;&gt;&gt;                 asyncInvocation.remove();<br>
&gt;&gt;&gt;&gt;&gt;            }<br>
&gt;&gt;&gt;&gt;&gt;        }));<br>
&gt;&gt;&gt;&gt;&gt;    }<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;}<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;But I&#39;ve got a feeling this works just by chance and not because the workaround is so clever.<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;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>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;Kind regards,<br>
&gt;&gt;&gt;&gt;&gt;Arjan Tijms<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;_______________________________________________<br>
cdi-dev mailing list <a href="mailto:cdi-dev@lists.jboss.org">cdi-dev@lists.jboss.org</a> <a href="https://lists.jboss.org/mailman/listinfo/cdi-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/cdi-dev</a> Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (<a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">http://www.apache.org/licenses/LICENSE-2.0.html</a>). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;_______________________________________________<br>
&gt;&gt;&gt;cdi-dev mailing list<br>
&gt;&gt;&gt;<a href="mailto:cdi-dev@lists.jboss.org">cdi-dev@lists.jboss.org</a><br>
&gt;&gt;&gt;<a href="https://lists.jboss.org/mailman/listinfo/cdi-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/cdi-dev</a><br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (<a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">http://www.apache.org/licenses/LICENSE-2.0.html</a>). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;--<br>
&gt;&gt;<br>
&gt;&gt;Antonio Goncalves<br>
&gt;&gt;Software architect, Java Champion and Pluralsight author<br>
&gt;&gt;<br>
&gt;&gt;Web site | Twitter | LinkedIn | Pluralsight | Paris JUG | Devoxx France<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;_______________________________________________<br>
&gt;cdi-dev mailing list<br>
&gt;<a href="mailto:cdi-dev@lists.jboss.org">cdi-dev@lists.jboss.org</a><br>
&gt;<a href="https://lists.jboss.org/mailman/listinfo/cdi-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/cdi-dev</a><br>
&gt;<br>
&gt;Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (<a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">http://www.apache.org/licenses/LICENSE-2.0.html</a>). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.<br>
&gt;<br>
&gt;<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr">Antonio Goncalves <br>Software architect, Java Champion and Pluralsight author<br><br><a href="http://www.antoniogoncalves.org" target="_blank">Web site</a> | <a href="http://twitter.com/agoncal" target="_blank">Twitter</a> | <a href="http://www.linkedin.com/in/agoncal" target="_blank">LinkedIn</a> | <a href="http://pluralsight.com/training/Authors/Details/antonio-goncalves" target="_blank">Pluralsight</a> | <a href="http://www.parisjug.org" target="_blank">Paris JUG</a> | <a href="http://www.devoxx.fr" target="_blank">Devoxx France</a></div></div>
</div>