Skip to content

NPE in push connection triggers uncontrolled message accumulation and eventual OutOfMemoryError #2527

@ponziani

Description

@ponziani

After a NullPointerException occurs during a push connection, Atmosphere begins accumulating messages in the org.atmosphere.cpr.DefaultBroadcaster queue indefinitely.
This marks the start of a steady rise in heap memory usage, which ultimately ends in an OutOfMemoryError.

Heap analysis shows that undelivered messages remain in the broadcaster’s internal messages-queue.

Example log trace:

 2025-10-01 10:14:19,336 - [c.v.f.s.c.PushAtmosphereHandler][qtp859703782-38918] ERROR - Exception in push connection
 java.lang.NullPointerException: Cannot invoke "org.atmosphere.cpr.AtmosphereResource.uuid()" because the return value of "org.atmosphere.cpr.AtmosphereResourceEvent.getResource()" is null
	at org.atmosphere.cpr.DefaultAtmosphereResourceSessionFactory$1.onDisconnect(DefaultAtmosphereResourceSessionFactory.java:29)
	at org.atmosphere.cpr.AtmosphereResourceImpl.onDisconnect(AtmosphereResourceImpl.java:755)
	at org.atmosphere.cpr.AtmosphereResourceImpl.notifyListeners(AtmosphereResourceImpl.java:647)
	at org.atmosphere.cpr.AtmosphereResourceImpl.notifyListeners(AtmosphereResourceImpl.java:628)
	at org.atmosphere.cpr.AsynchronousProcessor.completeLifecycle(AsynchronousProcessor.java:488)
	at org.atmosphere.interceptor.OnDisconnectInterceptor.inspect(OnDisconnectInterceptor.java:75)
	at org.atmosphere.cpr.AsynchronousProcessor.invokeInterceptors(AsynchronousProcessor.java:337)
	at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:194)
	at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:105)
	at org.atmosphere.container.Servlet30CometSupport.service(Servlet30CometSupport.java:67)
	at org.atmosphere.container.AbstractJetty9AsyncSupportWithWebSocket.service(AbstractJetty9AsyncSupportWithWebSocket.java:161)
	at org.atmosphere.container.Jetty9AsyncSupportWithWebSocket.service(Jetty9AsyncSupportWithWebSocket.java:35)
	at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:2292)
	at com.vaadin.flow.server.communication.PushRequestHandler.handleRequest(PushRequestHandler.java:284)
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1555)
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:365)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
	at org.apache.felix.http.base.internal.handler.ServletHandler.handle(ServletHandler.java:126)
	at org.apache.felix.http.base.internal.dispatch.InvocationChain.doFilter(InvocationChain.java:86)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:181)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:149)
	at org.apache.felix.http.base.internal.dispatch.InvocationChain.doFilter(InvocationChain.java:81)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:149)
	at org.apache.felix.http.base.internal.dispatch.InvocationChain.doFilter(InvocationChain.java:81)
	at org.apache.felix.http.base.internal.dispatch.Dispatcher$1.doFilter(Dispatcher.java:152)
	at org.apache.felix.http.base.internal.whiteboard.WhiteboardManager.invokePreprocessors(WhiteboardManager.java:986)
	at org.apache.felix.http.base.internal.dispatch.Dispatcher.dispatch(Dispatcher.java:94)
	at org.apache.felix.http.base.internal.dispatch.DispatcherServlet.service(DispatcherServlet.java:49)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:554)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:191)
	at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:181)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.Server.handle(Server.java:516)
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
	at java.base/java.lang.Thread.run(Thread.java:842)

Atmosphere Info

  • version: com.vaadin.external.atmosphere/atmosphere-runtime/2.7.3.slf4jvaadin6
  • extensions used: Vaadin Push (Flow 23.5.2),

Expected behavior
Atmosphere should handle a null resource gracefully


Additional context

  • We cannot reproduce the issue, but have seen it multiples times. The stacktrace does not always leads to a memory issue, it depends on the application it seems.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions