Skip to content

NullPointerException: Cannot invoke "org.eclipse.jetty.http.HttpFields$Mutable.contains(String)" because "this._fields" is null #5908

@thomas-k-git

Description

@thomas-k-git

Under contention, when using jetty + jersey and having a resource configured with org.glassfish.jersey.server.model.ResourceMethod.Builder#managedAsync and an EOF exception mapping filter and closing many client connections this NPE can be observed regularly.

Per analysis from the jetty team, the response object seems to wrongly re-used after completion (not in line with servlet spec) of the request triggering this NPE.

version(s)
jetty 12.0.19 + jersey-bom 2.46 (same behavior in 2.34 as in attached reproducer project)

Jetty Environment
ee8

Java version/vendor (use: java -version)
openjdk 21.0.7 2025-04-15 LTS
OpenJDK Runtime Environment Temurin-21.0.7+6 (build 21.0.7+6-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.7+6 (build 21.0.7+6-LTS, mixed mode, sharing)

OS type/version
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.5 LTS
Release: 22.04
Codename: jammy

Description
2025-04-30 13:36:16 GRAVE org.glassfish.jersey.server.ServerRuntime$Responder writeResponse - Error while closing the output stream in order to commit response. java.lang.NullPointerException: Cannot invoke "org.eclipse.jetty.http.HttpFields$Mutable.contains(String)" because "this._fields" is null at org.eclipse.jetty.ee8.nested.Response.containsHeader(Response.java:326) at org.glassfish.jersey.servlet.internal.ResponseWriter.writeResponseStatusAndHeaders(ResponseWriter.java:135) at org.glassfish.jersey.server.ServerRuntime$Responder$1.getOutputStream(ServerRuntime.java:625) at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:171) at org.glassfish.jersey.message.internal.CommittingOutputStream.flushBuffer(CommittingOutputStream.java:276) at org.glassfish.jersey.message.internal.CommittingOutputStream.commit(CommittingOutputStream.java:232) at org.glassfish.jersey.message.internal.CommittingOutputStream.close(CommittingOutputStream.java:247) at org.glassfish.jersey.message.internal.OutboundMessageContext.close(OutboundMessageContext.java:842) at org.glassfish.jersey.server.ContainerResponse.close(ContainerResponse.java:389) at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:707) at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:373) at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:419) at org.glassfish.jersey.server.ServerRuntime$AsyncResponder$4.run(ServerRuntime.java:872) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) 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:244) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265) at org.glassfish.jersey.server.ServerRuntime$AsyncResponder.resume(ServerRuntime.java:889) at org.glassfish.jersey.server.ServerRuntime$AsyncResponder.resume(ServerRuntime.java:867) at org.glassfish.jersey.server.ServerRuntime$AsyncResponder$2$1.run(ServerRuntime.java:821) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) 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:244) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265) at org.glassfish.jersey.server.ServerRuntime$AsyncResponder$2.run(ServerRuntime.java:811) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1583)

in specific setup with async thread pool, jersey, and EOFMapper

How to reproduce?
see attached project. running it a few times prodcues the NPE for me, sometimes also just issue 2.

npe-report.zip

Also seen issue 2
java.lang.IllegalStateException: AsyncContext completed and/or Request lifecycle recycled
at org.eclipse.jetty.ee8.nested.AsyncContextState.state(AsyncContextState.java:42)

Also seen issue 3
java.io.IOException: content-length 11 != 0 written
at org.eclipse.jetty.server.internal.HttpChannelState$ChannelCallback.succeeded(HttpChannelState.java:1548)

** Also seen*
In this similar setup in our more complex application we also saw threads of the secondary thread pool (in the repro called "CUSTOM") hanging forever, that we think is related, but will try to get a separate reproducer for that. But we think it might be related / caused originally by this NPE

see attached files.

npe-report.zip

originally reported at jetty in this ticket, but redirected here

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions