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

NullPointerException: Cannot invoke "com.vaadin.flow.server.VaadinSession.getErrorHandler()" logged when session is closed #12100

Closed
OlliTietavainenVaadin opened this issue Oct 20, 2021 · 10 comments · Fixed by #12531

Comments

@OlliTietavainenVaadin
Copy link
Member

Description of the bug / feature

If your session times out, you may get the following exception:

com.vaadin.flow.component.UI             : Cannot invoke "com.vaadin.flow.server.VaadinSession.getErrorHandler()" because the return value of "com.vaadin.flow.component.UI.getSession()" is null

java.lang.NullPointerException: Cannot invoke "com.vaadin.flow.server.VaadinSession.getErrorHandler()" because the return value of "com.vaadin.flow.component.UI.getSession()" is null
	at com.vaadin.flow.component.UI$2.handleError(UI.java:531) ~[flow-server-8.0.2.jar:8.0.2]
	at com.vaadin.flow.server.FutureAccess.handleError(FutureAccess.java:76) ~[flow-server-8.0.2.jar:8.0.2]
	at com.vaadin.flow.server.VaadinService.runPendingAccessTasks(VaadinService.java:2045) ~[flow-server-8.0.2.jar:8.0.2]
	at com.vaadin.flow.server.VaadinSession.unlock(VaadinSession.java:709) ~[flow-server-8.0.2.jar:8.0.2]
	at com.vaadin.flow.server.VaadinService.ensureAccessQueuePurged(VaadinService.java:2005) ~[flow-server-8.0.2.jar:8.0.2]
	at com.vaadin.flow.server.VaadinService.accessSession(VaadinService.java:1972) ~[flow-server-8.0.2.jar:8.0.2]
	at com.vaadin.flow.server.VaadinSession.access(VaadinSession.java:1012) ~[flow-server-8.0.2.jar:8.0.2]
	at com.vaadin.flow.server.VaadinService.fireSessionDestroy(VaadinService.java:632) ~[flow-server-8.0.2.jar:8.0.2]
	at com.vaadin.flow.server.VaadinSession.valueUnbound(VaadinSession.java:204) ~[flow-server-8.0.2.jar:8.0.2]
	at org.apache.catalina.session.StandardSession.removeAttributeInternal(StandardSession.java:1860) ~[tomcat-embed-core-9.0.52.jar:9.0.52]
	at org.apache.catalina.session.StandardSession.expire(StandardSession.java:861) ~[tomcat-embed-core-9.0.52.jar:9.0.52]
	at org.apache.catalina.session.StandardSession.isValid(StandardSession.java:660) ~[tomcat-embed-core-9.0.52.jar:9.0.52]
	at org.apache.catalina.session.ManagerBase.processExpires(ManagerBase.java:608) ~[tomcat-embed-core-9.0.52.jar:9.0.52]
	at org.apache.catalina.session.ManagerBase.backgroundProcess(ManagerBase.java:591) ~[tomcat-embed-core-9.0.52.jar:9.0.52]
	at org.apache.catalina.core.StandardContext.backgroundProcess(StandardContext.java:5622) ~[tomcat-embed-core-9.0.52.jar:9.0.52]
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1365) ~[tomcat-embed-core-9.0.52.jar:9.0.52]
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1369) ~[tomcat-embed-core-9.0.52.jar:9.0.52]
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1369) ~[tomcat-embed-core-9.0.52.jar:9.0.52]
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1347) ~[tomcat-embed-core-9.0.52.jar:9.0.52]
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[na:na]
	at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) ~[na:na]
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.52.jar:9.0.52]
	at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

This is due to getSession() returning null.

Minimal reproducible example

(fresh project from start.vaadin.com)
status-dashboard.zip

Expected behavior

Log should not show a NullPointerException but either nothing or a sensible message stating that the session has expired or somethingsimilar.

Actual behavior

NPE is shown in the log.

Versions:

- Vaadin / Flow version: Vaadin 21.0.2
- Java version: 17
- OS version: Windows 10
- Browser version (if applicable): n/a
- Application Server (if applicable): Spring Boot embedded Tomcat
- IDE (if applicable): n/a
@OlliTietavainenVaadin
Copy link
Member Author

Underlying exception that the errorhandler is trying to handle:

java.util.concurrent.ExecutionException: com.vaadin.flow.component.UIDetachedException
	at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
	at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
	at com.vaadin.flow.server.FutureAccess.get(FutureAccess.java:62)
	at com.vaadin.flow.server.VaadinService.runPendingAccessTasks(VaadinService.java:2042)
	at com.vaadin.flow.server.VaadinSession.unlock(VaadinSession.java:709)
	at com.vaadin.flow.server.VaadinService.ensureAccessQueuePurged(VaadinService.java:2005)
	at com.vaadin.flow.server.VaadinService.accessSession(VaadinService.java:1972)
	at com.vaadin.flow.server.VaadinSession.access(VaadinSession.java:1012)
	at com.vaadin.flow.server.VaadinService.fireSessionDestroy(VaadinService.java:632)
	at com.vaadin.flow.server.VaadinSession.valueUnbound(VaadinSession.java:204)
	at org.apache.catalina.session.StandardSession.removeAttributeInternal(StandardSession.java:1860)
	at org.apache.catalina.session.StandardSession.expire(StandardSession.java:861)
	at org.apache.catalina.session.StandardSession.isValid(StandardSession.java:660)
	at org.apache.catalina.session.ManagerBase.processExpires(ManagerBase.java:608)
	at org.apache.catalina.session.ManagerBase.backgroundProcess(ManagerBase.java:591)
	at org.apache.catalina.core.StandardContext.backgroundProcess(StandardContext.java:5622)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1365)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1369)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1369)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1347)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
	at java.base/java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:305)
	at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: com.vaadin.flow.component.UIDetachedException
	at com.vaadin.flow.component.UI.handleAccessDetach(UI.java:414)
	at com.vaadin.flow.component.UI.accessSynchronously(UI.java:431)
	at com.vaadin.flow.component.UI.access$000(UI.java:97)
	at com.vaadin.flow.component.UI$2.execute(UI.java:521)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
	at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
	at com.vaadin.flow.server.VaadinService.runPendingAccessTasks(VaadinService.java:2039)
```

@miguelatvaadin
Copy link
Contributor

Hi @OlliTietavainenVaadin ,

I'm sorry but I'm not able to reproduce the issue. Could you please provide which steps should be taken to see that exception?

I have tried logging out, invalidating the session, ..., but no NPE has was shown in the logs.

Thanks and best regards,

Miguel

@OlliTietavainenVaadin
Copy link
Member Author

OlliTietavainenVaadin commented Oct 27, 2021

At least I've been consistently been able to get the exception by running the project inside IntelliJ Idea, with mvn spring-boot:run, and leaving it running for enough time (30 minutes, or maybe longer?)

Edit: also should happen with starting the app by debugging the Application.java, as I was able to add a breakpoint to Vaadin Service

@miguelatvaadin
Copy link
Contributor

ok. Great. Thanks, Olli. I will try to reproduce it

@miguelatvaadin
Copy link
Contributor

Hi Olli,

definitely I'm not able to reproduce it. I have left the application running for more than 1 hour to let the session end several times and I have never experienced the issue you describe.

Surely one collegue will contact you during next days, in order to dig deeper into this.

Thanks!

@OlliTietavainenVaadin
Copy link
Member Author

Unfortunately, I've also had problems being able to reproduce the issue. It's weird because when I was able to reproduce the issue, it was consistent (even if slow to appear) - and when I was running the application in Debug, I was able to add the breakpoint and see the issue occur live.

@Artur-
Copy link
Member

Artur- commented Dec 7, 2021

Saw this today in an start.vaadin.com "all" project using 14.7.8, running with command line Maven. Potentially related to using a collaboration engine view in the session

@Artur-
Copy link
Member

Artur- commented Dec 8, 2021

What happens in my case is:

  1. The session times out
  2. fireSessionDestroy is called and this uses session.access
  3. session.access first clears the access queue by running whatever is pending
  4. There is a pending com.vaadin.collaborationengine.ComponentConnectionContext$$Lambda$1108.0x00000008011b9a28 command in the access queue
  5. UI.access throws UIDetachedException when running the command
  6. The exception is passed to the command itself if it is of type ErrorHandlingCommand but in this case UI.access has wrapped the command into an ErrorHandlingCommand and handles the exception in UI.access as
    getSession().getErrorHandler()
    .error(new ErrorEvent(exception));

It seems that the problem is that the wrapping in UI.access assumes that the UI is always attached when an error occurs. That is not true.

vaadin-bot added a commit that referenced this issue Dec 16, 2021
@vaadin-bot
Copy link
Collaborator

This ticket/PR has been released with platform 22.0.2.

@vaadin-bot
Copy link
Collaborator

This ticket/PR has been released with platform 14.8.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants