Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intermittent java.lang.IllegalStateException: DataChunkInputStream needs to be handled in separate thread to prevent deadlock #2371

Closed
jansupol opened this issue Sep 16, 2020 · 2 comments
Assignees
Labels
2.x Issues for 2.x version branch bug Something isn't working P2 SE webclient

Comments

@jansupol
Copy link
Contributor

A single test runs 1000x and intermittently fails.

@Verdent Verdent self-assigned this Sep 16, 2020
@Verdent Verdent added 2.x Issues for 2.x version branch bug Something isn't working SE webclient labels Sep 16, 2020
@m0mus m0mus added the P2 label Sep 17, 2020
@jansupol
Copy link
Contributor Author

The stack trace:

java.lang.IllegalStateException: DataChunkInputStream needs to be handled in separate thread to prevent deadlock.
at io.helidon.media.common.DataChunkInputStream.validate(DataChunkInputStream.java:190)
at io.helidon.media.common.DataChunkInputStream.read(DataChunkInputStream.java:123)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:133)
at org.glassfish.jersey.message.internal.EntityInputStream.read(EntityInputStream.java:79)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream.read(ReaderInterceptorExecutor.java:273)
at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.base/java.io.InputStreamReader.read(InputStreamReader.java:185)
at java.base/java.io.Reader.read(Reader.java:229)
at org.glassfish.jersey.message.internal.ReaderWriter.readFromAsString(ReaderWriter.java:152)
at org.glassfish.jersey.message.internal.ReaderWriter.readFromAsString(ReaderWriter.java:137)
at org.glassfish.jersey.message.internal.AbstractMessageReaderWriterProvider.readFromAsString(AbstractMessageReaderWriterProvider.java:94)
at org.glassfish.jersey.message.internal.StringMessageProvider.readFrom(StringMessageProvider.java:54)
at org.glassfish.jersey.message.internal.StringMessageProvider.readFrom(StringMessageProvider.java:36)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:233)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:212)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:132)
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1072)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:885)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:819)
at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:298)
at org.glassfish.jersey.client.InboundJaxrsResponse$1.call(InboundJaxrsResponse.java:91)
at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.glassfish.jersey.internal.Errors.process(Errors.java:205)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:365)
at org.glassfish.jersey.client.InboundJaxrsResponse.runInScopeIfPossible(InboundJaxrsResponse.java:240)
at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:88)
at org.example.ConnectorTest.queryGetTest(ConnectorTest.java:52)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)

@Verdent
Copy link
Member

Verdent commented Sep 23, 2020

This is actually bug in DataChunkInputStream and its protection against deadlock when it is handled by the same thread as response in WebClient.

This problem is caused by race condition HelidonConnector class at line 174. If the CompletionStage returned by submit is completed before thenCompose is added to it, DataChunkInputStream instance will be created by the same thread as is used to run the test.

I have created a new branch in my repository which contains possible workaround (currently commented) in HelidonConnector class if this is needed to be hotfixed. Currently this behavior occurs just rarely and mainly on slower computers. I am not creating PR so far as requested by Tomas Langer and we will try to come up with proper fix for this bug.

My branch which contains workaround and test -> https://github.com/Verdent/helidon/tree/helidon-connector-race

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.x Issues for 2.x version branch bug Something isn't working P2 SE webclient
Projects
Archived in project
Development

No branches or pull requests

3 participants