Repository navigation
issues with apache httpclient 5.1.x #1789
Copy link
Copy link
Closed
Description
When I switch the httpclient version from 5.0.x to 5.1.x, docker-java has problems communicating with docker - the process hangs with such a stack trace:
"main" #1 prio=5 os_prio=0 cpu=4140.63ms elapsed=64.25s tid=0x0000021b0a61af20 nid=0x544c waiting on condition [0x000000a03dff8000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park([email protected]/Native Method)
- parking to wait for <0x00000006070433f8> (a java.util.concurrent.CompletableFuture$Signaller)
at java.util.concurrent.locks.LockSupport.park([email protected]/LockSupport.java:211)
at java.util.concurrent.CompletableFuture$Signaller.block([email protected]/CompletableFuture.java:1864)
at java.util.concurrent.ForkJoinPool.unmanagedBlock([email protected]/ForkJoinPool.java:3463)
at java.util.concurrent.ForkJoinPool.managedBlock([email protected]/ForkJoinPool.java:3434)
at java.util.concurrent.CompletableFuture.waitingGet([email protected]/CompletableFuture.java:1898)
at java.util.concurrent.CompletableFuture.get([email protected]/CompletableFuture.java:2072)
at java.nio.channels.Channels$2.read([email protected]/Channels.java:238)
- locked <0x000000060371f9f8> (a java.nio.channels.Channels$2)
at org.apache.hc.core5.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:149)
at org.apache.hc.core5.http.impl.io.BHttpConnectionBase.fillInputBuffer(BHttpConnectionBase.java:265)
at org.apache.hc.core5.http.impl.io.BHttpConnectionBase.isStale(BHttpConnectionBase.java:295)
at org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnection.isStale(DefaultBHttpClientConnection.java:67)
at org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:287)
- locked <0x0000000607043268> (a org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager$1)
at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.acquireEndpoint(InternalExecRuntime.java:109)
at org.apache.hc.client5.http.impl.classic.ConnectExec.execute(ConnectExec.java:119)
at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57)
at org.apache.hc.client5.http.impl.classic.ProtocolExec.execute(ProtocolExec.java:175)
at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57)
at org.apache.hc.client5.http.impl.classic.HttpRequestRetryExec.execute(HttpRequestRetryExec.java:96)
at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57)
at org.apache.hc.client5.http.impl.classic.ContentCompressionExec.execute(ContentCompressionExec.java:133)
at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57)
at org.apache.hc.client5.http.impl.classic.RedirectExec.execute(RedirectExec.java:115)
at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
at org.apache.hc.client5.http.impl.classic.InternalHttpClient.doExecute(InternalHttpClient.java:170)
at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:67)
at com.github.dockerjava.httpclient5.ApacheDockerHttpClientImpl.execute(ApacheDockerHttpClientImpl.java:175)
at com.github.dockerjava.httpclient5.ApacheDockerHttpClient.execute(ApacheDockerHttpClient.java:9)
at com.github.dockerjava.core.DefaultInvocationBuilder.execute(DefaultInvocationBuilder.java:228)
at com.github.dockerjava.core.DefaultInvocationBuilder.get(DefaultInvocationBuilder.java:202)
at com.github.dockerjava.core.DefaultInvocationBuilder.get(DefaultInvocationBuilder.java:74)
at com.github.dockerjava.core.exec.ListImagesCmdExec.execute(ListImagesCmdExec.java:41)
at com.github.dockerjava.core.exec.ListImagesCmdExec.execute(ListImagesCmdExec.java:16)
at com.github.dockerjava.core.exec.AbstrSyncDockerCmdExec.exec(AbstrSyncDockerCmdExec.java:21)
at com.github.dockerjava.core.command.AbstrDockerCmd.exec(AbstrDockerCmd.java:35)
OS: Windows 10 with Docker Desktop
Docker-Java: 3.2.11 and 3.2.12
JDK: Corretto 17.0.1
Some commands seem to succeed but sooner or later one hangs forever. So far I have not been able to create a small reproducer - executing e.g. listImages in a loop did not produce the issue.
Metadata
Metadata
Assignees
Labels
No labels
Activity
peterdnight commentedon Jan 21, 2022
Same issue - thanks for taking time to report (although i still burned many hours isolating JVM crashes)
dimovelev commentedon Jan 21, 2022
@peterdnight i switched to the zerodep client - it seems to be a shaded httpclient5 so it does not clash with the version i have in the remaining part of my application. I guess that is the safer bet for future updates and i will stick to it.
dimovelev commentedon Jan 21, 2022
After reading through the other issue I have a short reproducer:
The second list images hangs forever.
The crucial part is sleeping for at least 2 seconds (1 second is fine). With that and going through the apache httpclient commits I would guess that the issue is this one - apache/httpcomponents-client@10e2deb
dimovelev commentedon Jan 21, 2022
So the connection staleness check in org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager seems to block forever. It is triggered (with default configuration) after 2 seconds of inactivity. If you change that to -1 the check is disabled and the code above does not block. you can call this method after creating the client to change the value:
So I guess a change in com.github.dockerjava.httpclient5.ApacheDockerHttpClientImpl will be required to set this value.
dimovelev commentedon Jan 21, 2022
The connection staleness check in apache httpclient seems to rely on modifying the socket timeout to 1 ms then trying to read something and resetting the timeout back to the original value. I guess that this fails in our case - the timeout is not reset and thus the read blocks forever (as the original timeout was 0).
dimovelev commentedon Jan 21, 2022
that was a big waste of time. the issue has been fixed (well the timeout set to -1 as i figured out above) in November 2021 - see #1727 . The latest release of docker-java does not include the fix.
@bsideup when is the next released planned?
peterdnight commentedon Jan 24, 2022
@dimovelev - i feel your pain. fyi - if you are curious regarding my use case, check out my docker tutorial:
https://www.youtube.com/playlist?list=PLETtnz3MXNMUBFq_kSSXrXm1lnp10rt0I
bsideup commentedon Feb 15, 2022
Should be fixed in 3.2.13