Hello, I try to get a JSF (Mojarra 2.3.3) application working with Server Push and keep getting a NPE when using HTTP/2. Tested with JDK8 + OpenSSL and JDK9 + JSSE. Application in question is Primefaces 6.1 Showcase, modified to use Servlet 4 and Mojarra 2.3.3. The Exception Stacktrace: java.lang.NullPointerException at org.apache.coyote.http2.Http2AsyncUpgradeHandler$AsyncHeaderFrameBuffers.access$200(Http2AsyncUpgradeHandler.java:425) at org.apache.coyote.http2.Http2AsyncUpgradeHandler.writeHeaders(Http2AsyncUpgradeHandler.java:158) at org.apache.coyote.http2.Http2UpgradeHandler.push(Http2UpgradeHandler.java:1120) at org.apache.coyote.http2.Stream.push(Stream.java:672) at org.apache.coyote.http2.Stream.push(Stream.java:642) at org.apache.coyote.http2.StreamProcessor.doPush(StreamProcessor.java:280) at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:490) at org.apache.coyote.Request.action(Request.java:432) at org.apache.catalina.core.ApplicationPushBuilder.push(ApplicationPushBuilder.java:370) at com.sun.faces.context.ExternalContextImpl.pushIfPossibleAndNecessary(ExternalContextImpl.java:704) at com.sun.faces.context.ExternalContextImpl.encodeResourceURL(ExternalContextImpl.java:662) at javax.faces.context.ExternalContextWrapper.encodeResourceURL(ExternalContextWrapper.java:164) at com.sun.faces.renderkit.html_basic.ScriptStyleBaseRenderer.encodeEnd(ScriptStyleBaseRenderer.java:246) at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:949) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1912) at org.primefaces.renderkit.HeadRenderer.encodeBegin(HeadRenderer.java:97) at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:892) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1903) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1908) at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:491) at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:194) at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:151) at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:151) at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:126) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100) at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:223) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:671) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:100) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.primefaces.showcase.filter.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:32) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) at org.apache.coyote.http2.StreamProcessor.service(StreamProcessor.java:324) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.http2.StreamProcessor.process(StreamProcessor.java:72) at org.apache.coyote.http2.StreamRunnable.run(StreamRunnable.java:35) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Unknown Source)
The exception is too odd to be able to make something out of it at the moment. Since you're using NIO2, you can try NIO instead.
It seemes to be triggered by a flaw in web application layer. Google Chrome keeps closing the SSL connection due to Server Push protocol violations. https://github.com/javaserverfaces/mojarra/issues/4329 Nevertheless I'd suggest to add a [null] check at Http2AsyncUpgradeHandler.java:158 as return value of org.apache.coyote.http2.Http2UpgradeHandler.doWriteHeaders(Stream, int, MimeHeaders, boolean, int) is obviously @Nullable: protected HeaderFrameBuffers doWriteHeaders(Stream stream, int pushedStreamId, MimeHeaders mimeHeaders, boolean endOfStream, int payloadSize) throws IOException { ... if (!stream.canWrite()) { return null; } ... } This turns the NullPointerException into a more expressive one: org.apache.catalina.connector.ClientAbortException: org.apache.coyote.CloseNowException: Connection [1], Stream [10], This stream is not writable Caused by: org.apache.coyote.CloseNowException: Connection [1], Stream [10], This stream is not writable Tahnks for quick response and kind regards
Thanks a lot for the testing and the fix proposal, this actually looked like a possibly complex problem, so I guess it was almost normal besides the scary stack. This NPE was added as part of a recent refactoring, and NIO was not affected as it did not use the return value. The null check fix will be in 9.0.5.