Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-7037

@Suspended can be broken on tomcat

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 3.1.7
    • 3.1.8, 3.0.11, 3.2.0
    • None
    • None
    • Unknown

    Description

      For AsyncContext usages, tomcat ensures the non container threads wait for the container thread to exit the execution (the one starting the async context) to avoid concurrency issue.

      For cxf it means you can resume() in a user thread on an AsyncResponse while you execute AsyncResponseImpl.suspendContinuationIfNeeded().

      This can lead to a lock preventing the request to complete.

      Here is a sample thread:

      "managed-thread-3@7750" daemon prio=5 tid=0x48 nid=NA waiting
        java.lang.Thread.State: WAITING
           blocks http-nio-24622-exec-3@7702
            at java.lang.Object.wait(Object.java:-1)
            at java.lang.Object.wait(Object.java:502)
            at org.apache.coyote.AsyncStateMachine.pauseNonContainerThread(AsyncStateMachine.java:452)
            at org.apache.coyote.AsyncStateMachine.asyncDispatch(AsyncStateMachine.java:315)
            at org.apache.coyote.http11.Http11Processor.action(Http11Processor.java:858)
            at org.apache.coyote.Request.action(Request.java:390)
            at org.apache.catalina.core.AsyncContextImpl.dispatch(AsyncContextImpl.java:203)
            - locked <0x21ed> (a java.lang.Object)
            at org.apache.catalina.core.AsyncContextImpl.dispatch(AsyncContextImpl.java:171)
            at org.apache.catalina.core.AsyncContextImpl.dispatch(AsyncContextImpl.java:165)
            at org.apache.openejb.server.httpd.EEFilter$AsynContextWrapper.dispatch(EEFilter.java:171)
            at org.apache.cxf.transport.http.Servlet3ContinuationProvider$Servlet3Continuation.redispatch(Servlet3ContinuationProvider.java:125)
            at org.apache.cxf.transport.http.Servlet3ContinuationProvider$Servlet3Continuation.resume(Servlet3ContinuationProvider.java:131)
            at org.apache.cxf.jaxrs.impl.AsyncResponseImpl.doResumeFinal(AsyncResponseImpl.java:96)
            - locked <0x2196> (a org.apache.cxf.jaxrs.impl.AsyncResponseImpl)
            at org.apache.cxf.jaxrs.impl.AsyncResponseImpl.doResume(AsyncResponseImpl.java:89)
            at org.apache.cxf.jaxrs.impl.AsyncResponseImpl.resume(AsyncResponseImpl.java:73)
            at com.github.rmannibucau.rblog.jaxrs.async.AsyncInterceptor.lambda$async$0(AsyncInterceptor.java:63)
            at com.github.rmannibucau.rblog.jaxrs.async.AsyncInterceptor$$Lambda$55.375198754.run(Unknown Source:-1)
            at com.github.rmannibucau.rblog.jaxrs.async.AsyncInterceptor$TransactionProvider.run(AsyncInterceptor.java:148)
            at sun.reflect.GeneratedMethodAccessor95.invoke(Unknown Source:-1)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.apache.webbeans.intercept.AbstractInvocationContext.directProceed(AbstractInvocationContext.java:113)
            at org.apache.webbeans.intercept.AbstractInvocationContext.proceed(AbstractInvocationContext.java:106)
            at org.apache.webbeans.intercept.InterceptorInvocationContext.proceed(InterceptorInvocationContext.java:67)
            at org.apache.openejb.cdi.transactional.InterceptorBase.intercept(InterceptorBase.java:66)
            at org.apache.openejb.cdi.transactional.RequiredInterceptor.intercept(RequiredInterceptor.java:35)
            at sun.reflect.GeneratedMethodAccessor85.invoke(Unknown Source:-1)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.apache.webbeans.component.InterceptorBean.intercept(InterceptorBean.java:136)
            at org.apache.webbeans.intercept.InterceptorInvocationContext.proceed(InterceptorInvocationContext.java:63)
            at org.apache.webbeans.intercept.DefaultInterceptorHandler.invoke(DefaultInterceptorHandler.java:139)
            at com.github.rmannibucau.rblog.jaxrs.async.AsyncInterceptor$TransactionProvider$$OwbInterceptProxy0.run(com/github/rmannibucau/rblog/jaxrs/async/AsyncInterceptor$TransactionProvider.java:-1)
            at com.github.rmannibucau.rblog.jaxrs.async.AsyncInterceptor$TransactionProvider$$OwbNormalScopeProxy0.run(com/github/rmannibucau/rblog/jaxrs/async/AsyncInterceptor$TransactionProvider.java:-1)
            at com.github.rmannibucau.rblog.jaxrs.async.AsyncInterceptor$Metas.lambda$runInTransaction$6(AsyncInterceptor.java:130)
            at com.github.rmannibucau.rblog.jaxrs.async.AsyncInterceptor$Metas$$Lambda$56.1727885795.run(Unknown Source:-1)
            at com.github.rmannibucau.rblog.jaxrs.async.AsyncInterceptor$Metas.lambda$toJaxRs$7(AsyncInterceptor.java:136)
            at com.github.rmannibucau.rblog.jaxrs.async.AsyncInterceptor$Metas$$Lambda$57.1956863343.run(Unknown Source:-1)
            at org.apache.openejb.threads.task.CURunnable$1.call(CURunnable.java:35)
            at org.apache.openejb.threads.task.CURunnable$1.call(CURunnable.java:32)
            at org.apache.openejb.threads.task.CUTask.invoke(CUTask.java:89)
            at org.apache.openejb.threads.task.CURunnable.run(CURunnable.java:32)
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            at java.lang.Thread.run(Thread.java:745)
      
      "http-nio-24622-exec-3@7702" daemon prio=5 tid=0x41 nid=NA waiting for monitor entry
        java.lang.Thread.State: BLOCKED
           waiting for managed-thread-3@7750 to release lock on <0x2196> (a org.apache.cxf.jaxrs.impl.AsyncResponseImpl)
            at org.apache.cxf.jaxrs.impl.AsyncResponseImpl.suspendContinuationIfNeeded(AsyncResponseImpl.java:263)
            at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:191)
      

      Solution would be to not synchronize both method and probably move to a volatile state

      Attachments

        Issue Links

          Activity

            People

              sergey_beryozkin Sergey Beryozkin
              romain.manni-bucau Romain Manni-Bucau
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: