[ 
https://issues.apache.org/jira/browse/CXF-8926?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18087777#comment-18087777
 ] 

Freeman Yue Fang commented on CXF-8926:
---------------------------------------

I am revisiting this issue and I can reproduce the MTOM attachment hang problem 
with latest CXF versions. I will attach the MTOMAttachmentStallTest.java which 
demonstrate this problem.

The  root cause is when a CXF client sends a large MTOM attachment using 
HttpClientHTTPConduit (Java 11+ HttpClient), the attachment bytes are written 
through a PipedOutputStream → PipedInputStream pipe. The Java HttpClient reads 
from the PipedInputStream on its own thread and pushes bytes to the TCP socket.

When the server accepts the TCP connection but never reads

1. The server's TCP receive buffer fills (~4 MB on macOS)
2. The client's TCP send buffer fills (~4 MB)
3. Java's HttpClient backs off — it stops consuming from the PipedInputStream
4. The 4 KB PipedInputStream buffer fills up
5. PipedOutputStream.write() calls PipedInputStream.receive(), which calls 
awaitSpace() and blocks on Object.wait() — indefinitely

The receiveTimeout configured on HTTPClientPolicy is set as 
HttpRequest.timeout() on the Java HttpClient, but that timeout only fires after 
the response phase begins — it cannot reach back and unblock a 
PipedOutputStream.write() that is already stuck in awaitSpace().

I'm working on a solution.

Freeman

> MTOM - Lock while processing attachment
> ---------------------------------------
>
>                 Key: CXF-8926
>                 URL: https://issues.apache.org/jira/browse/CXF-8926
>             Project: CXF
>          Issue Type: Bug
>            Reporter: wilfried
>            Assignee: Freeman Yue Fang
>            Priority: Major
>
> I'm currently implementing a SOAP client to send document with CXF 4.0.1 (the 
> application is quarkus based).
> My client is working fine when firewall is open between my machine and the 
> target server, but in case firewall is closed (for QA environment for 
> example), I was expecting to get a timeout, but it's not the case. The SOAP 
> client stops its execution to the interceptor *AttachmentOutEndingInterceptor 
> *and waits indefinitely.
> After profiling the application, I found out a lock as shown by the below 
> thread dump:
> {code:java}
> "executor-thread-2" #296 daemon prio=5 os_prio=0 cpu=31.25ms elapsed=201.04s 
> tid=0x0000019f9cd475d0 nid=0x5cf8 in Object.wait() [0x0000009645dfe000]
>    java.lang.Thread.State: TIMED_WAITING (on object monitor)
>         at java.lang.Object.wait([email protected]/Native Method)
>         - waiting on <no object reference available>
>         at 
> java.io.PipedInputStream.awaitSpace([email protected]/PipedInputStream.java:273)
>         at 
> java.io.PipedInputStream.receive([email protected]/PipedInputStream.java:231)
>         - locked <0x0000000613854b08> (a java.io.PipedInputStream)
>         at 
> java.io.PipedOutputStream.write([email protected]/PipedOutputStream.java:150)
>         at 
> org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:51)
>         at 
> org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69)
>         at 
> org.apache.cxf.io.CacheAndWriteOutputStream.write(CacheAndWriteOutputStream.java:81)
>         at jakarta.activation.DataHandler.writeTo(DataHandler.java:283)
>         at 
> org.apache.cxf.attachment.AttachmentSerializer.writeAttachments(AttachmentSerializer.java:318)
>         at 
> org.apache.cxf.interceptor.AttachmentOutInterceptor$AttachmentOutEndingInterceptor.handleMessage(AttachmentOutInterceptor.java:126)
>         at 
> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
>         - locked <0x0000000613856e30> (a 
> org.apache.cxf.phase.PhaseInterceptorChain)
>         at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:528)
>         at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:439)
>         at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:354)
>         at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:312)
>         at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
>         at 
> org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:140)
>         at jdk.proxy7.$Proxy235.addMessage(jdk.proxy7/Unknown Source)
>         at 
> lu.etat.ci.fwt.soap.SOAPTestController.callSaySomethingMtomSecuredCIDUT(SOAPTestController.java:138)
>         at 
> lu.etat.ci.fwt.soap.SOAPTestController$quarkusrestinvoker$callSaySomethingMtomSecuredCIDUT_1b14f2d5ed1a4d42c824e7582903a9f19063cae3.invoke(Unknown
>  Source)
>         at 
> org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
>         at 
> io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
>         at 
> org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:145)
>         at 
> io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:576)
>         at 
> org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
>         at 
> org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1512)
>         at 
> org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
>         at 
> org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
>         at 
> io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
>         at java.lang.Thread.run([email protected]/Thread.java:833)
> {code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to