jetty.project icon indicating copy to clipboard operation
jetty.project copied to clipboard

Patch and test two related NPEs in AsyncMiddleManServlet and HttpExchange

Open garydgregory opened this issue 1 year ago • 2 comments

Patches and test two related NullPointerException in AsyncMiddleManServlet.onContinue() and org.eclipse.jetty.client.transport.HttpExchange.getRequest()

Tests a hard to reproduce timing-based NullPointerException. It does not always happen, it may be related to how busy the CPU is; using "CPU Stres" from https://learn.microsoft.com/en-us/sysinternals/downloads/cpustres helps make the failure happen more often when I peg the CPU at 92% busy or above.

This test is a great simplification of a set up used in real life where both NullPointerException below occur.

java.lang.NullPointerException: Cannot invoke "java.lang.Runnable.run()" because "action" is null
    at org.eclipse.jetty.ee9.proxy/org.eclipse.jetty.ee9.proxy.AsyncMiddleManServlet.onContinue(AsyncMiddleManServlet.java:178)
    at org.eclipse.jetty.ee9.proxy/org.eclipse.jetty.ee9.proxy.AbstractProxyServlet$ProxyContinueProtocolHandler.onContinue(AbstractProxyServlet.java:862)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.ContinueProtocolHandler$ContinueListener.onSuccess(ContinueProtocolHandler.java:83)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.ResponseListeners.notifySuccess(ResponseListeners.java:273)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.ResponseListeners.notifySuccess(ResponseListeners.java:265)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpReceiver.lambda$4(HttpReceiver.java:359)
    at org.eclipse.jetty.util/org.eclipse.jetty.util.thread.SerializedInvoker$Link.run(SerializedInvoker.java:191)
    at org.eclipse.jetty.util/org.eclipse.jetty.util.thread.SerializedInvoker.run(SerializedInvoker.java:117)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpReceiver.responseHeaders(HttpReceiver.java:243)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.internal.HttpReceiverOverHTTP.lambda$2(HttpReceiverOverHTTP.java:435)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.internal.HttpReceiverOverHTTP.parse(HttpReceiverOverHTTP.java:320)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.internal.HttpReceiverOverHTTP.parseAndFill(HttpReceiverOverHTTP.java:250)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.internal.HttpReceiverOverHTTP.receive(HttpReceiverOverHTTP.java:76)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.internal.HttpChannelOverHTTP.receive(HttpChannelOverHTTP.java:97)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.internal.HttpConnectionOverHTTP.onFillable(HttpConnectionOverHTTP.java:207)
    at org.eclipse.jetty.io/org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:322)
    at org.eclipse.jetty.io/org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:99)
    at org.eclipse.jetty.io/org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
    at org.eclipse.jetty.util/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:478)
    at org.eclipse.jetty.util/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:441)
    at org.eclipse.jetty.util/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:293)
    at org.eclipse.jetty.util/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.produce(AdaptiveExecutionStrategy.java:195)
    at org.eclipse.jetty.util/org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:979)
    at org.eclipse.jetty.util/org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1209)
    at org.eclipse.jetty.util/org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1164)
    at java.base/java.lang.Thread.run(Thread.java:840)

Once AsyncMiddleManServlet.onContinue() is fixed to avoid the above NPE, you may get a different NPE, in the client:

java.lang.NullPointerException: Cannot invoke
"org.eclipse.jetty.client.transport.HttpExchange.getRequest()" because "exchange" is null
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpSender.abortRequest(HttpSender.java:237)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpSender.internalAbort(HttpSender.java:389)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpSender$ContentSender.onCompleteFailure(HttpSender.java:609)
    at org.eclipse.jetty.util/org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:335)
    at org.eclipse.jetty.util/org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:231)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpSender.send(HttpSender.java:85)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.internal.HttpChannelOverHTTP.send(HttpChannelOverHTTP.java:86)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpChannel.send(HttpChannel.java:142)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpConnection.send(HttpConnection.java:112)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.internal.HttpConnectionOverHTTP$Delegate.send(HttpConnectionOverHTTP.java:330)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.internal.HttpConnectionOverHTTP.send(HttpConnectionOverHTTP.java:159)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpDestination.send(HttpDestination.java:444)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpDestination.process(HttpDestination.java:420)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpDestination.process(HttpDestination.java:375)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpDestination.send(HttpDestination.java:358)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpDestination.send(HttpDestination.java:352)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpDestination.send(HttpDestination.java:329)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpDestination.send(HttpDestination.java:308)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpRequest.sendAsync(HttpRequest.java:751)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpDestination.send(HttpDestination.java:303)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpRequest.send(HttpRequest.java:744)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.CompletableResponseListener.send(CompletableResponseListener.java:79)
    at org.eclipse.jetty.client/org.eclipse.jetty.client.transport.HttpRequest.send(HttpRequest.java:707)
    at [email protected]/org.eclipse.jetty.ee9.proxy.AsyncMiddleManServletTest.testServletOnContinueNullPointerException(AsyncMiddleManServletTest.java:253)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

garydgregory avatar Jun 08 '24 16:06 garydgregory

The issue is https://github.com/jetty/jetty.project/issues/11841

garydgregory avatar Jun 08 '24 18:06 garydgregory

Hello @olamy, Would you mind taking a look at this PR please?

garydgregory avatar Jun 10 '24 14:06 garydgregory

@garydgregory I'm closing this PR in favor of #12113.

sbordet avatar Jul 31 '24 13:07 sbordet

@sbordet Thank you for the update, I'll watch and wait for #12113 then...

garydgregory avatar Jul 31 '24 15:07 garydgregory