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

Exception on server bootup after updating full project (including database) #160

Closed
FollowSteph opened this issue Oct 4, 2019 · 24 comments · Fixed by #2125
Closed

Exception on server bootup after updating full project (including database) #160

FollowSteph opened this issue Oct 4, 2019 · 24 comments · Fixed by #2125

Comments

@FollowSteph
Copy link
Contributor

Just did a full update, including database, etc., and on first boot up of the server I got this in the server logs.

2019-10-03 21:28:18.376 ERROR 12792 --- [  restartedMain] o.a.catalina.session.StandardManager     : Exception loading sessions from persistent storage

java.lang.ClassCastException: class [Ljava.lang.StackTraceElement; cannot be cast to class java.lang.String ([Ljava.lang.StackTraceElement; and java.lang.String are in module java.base of loader 'bootstrap')
	at java.base/java.io.ObjectInputStream.readTypeString(ObjectInputStream.java:1671) ~[na:na]
	at java.base/java.io.ObjectStreamClass.readNonProxy(ObjectStreamClass.java:793) ~[na:na]
	at java.base/java.io.ObjectInputStream.readClassDescriptor(ObjectInputStream.java:902) ~[na:na]
	at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1875) ~[na:na]
	at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1772) ~[na:na]
	at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2060) ~[na:na]
	at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594) ~[na:na]
	at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:430) ~[na:na]
	at org.apache.catalina.session.StandardSession.doReadObject(StandardSession.java:1576) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:1048) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.session.StandardManager.doLoad(StandardManager.java:218) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.session.StandardManager.load(StandardManager.java:162) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.session.StandardManager.startInternal(StandardManager.java:354) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5160) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264) ~[na:na]
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java) ~[na:na]
	at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140) ~[na:na]
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:841) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264) ~[na:na]
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java) ~[na:na]
	at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140) ~[na:na]
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.core.StandardService.startInternal(StandardService.java:421) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:932) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.apache.catalina.startup.Tomcat.start(Tomcat.java:456) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
	at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:105) ~[spring-boot-2.1.7.RELEASE.jar:2.1.7.RELEASE]
	at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:86) ~[spring-boot-2.1.7.RELEASE.jar:2.1.7.RELEASE]
	at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:416) ~[spring-boot-2.1.7.RELEASE.jar:2.1.7.RELEASE]
	at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:180) ~[spring-boot-2.1.7.RELEASE.jar:2.1.7.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:180) ~[spring-boot-2.1.7.RELEASE.jar:2.1.7.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:153) ~[spring-boot-2.1.7.RELEASE.jar:2.1.7.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.1.7.RELEASE.jar:2.1.7.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:743) ~[spring-boot-2.1.7.RELEASE.jar:2.1.7.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:390) ~[spring-boot-2.1.7.RELEASE.jar:2.1.7.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[spring-boot-2.1.7.RELEASE.jar:2.1.7.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1214) ~[spring-boot-2.1.7.RELEASE.jar:2.1.7.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1203) ~[spring-boot-2.1.7.RELEASE.jar:2.1.7.RELEASE]
	at io.skymind.pathmind.PathmindApplication.main(PathmindApplication.java:18) ~[classes/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.1.7.RELEASE.jar:2.1.7.RELEASE]


@slinlee slinlee added the Type: Bug Something isn't working label Oct 4, 2019
@slinlee slinlee added this to To do in Pathmind Oct 16, 2019
@slinlee slinlee moved this from To do to Inbox - To Triage in Pathmind Nov 1, 2019
@slinlee slinlee moved this from Inbox - To Triage to To do in Pathmind Nov 7, 2019
@slinlee slinlee moved this from To do to Bugs in Pathmind Feb 3, 2020
@kepricon
Copy link
Contributor

kepricon commented Feb 5, 2020

I still have this error when restarting pathmind on my local

@stale
Copy link

stale bot commented Apr 5, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Apr 5, 2020
@FollowSteph
Copy link
Contributor Author

This is still an issue.

@onuridrisoglu
Copy link
Contributor

@FollowSteph @slinlee I made some investigation on this error, here are my findings:

  • Tomcat has a feature that persists the active sessions on filesystem while shutting down, and restores them back after restart. So that, after server restart you don't need to login the application again. This feature is disabled by default, but it's enabled by spring-boot-devtools.
  • This exception (regardless of project update) happens exactly at this stage. While persisting the user session, some components cannot be serialized because they are not serializable (for example EmailNotificationService), at server startup these sessions are tried to be restored but this operation fails - because session couldn't be serialized properly. As a result, this exception is logged in console. The exception is a bit misleading because the actual problem occurs during server shutdown, but it's not logged. There is an issue in spring-boot project for this case : JUL-based logging performed during close of application context is lost spring-projects/spring-boot#9457
  • I tried to make all components implement Serializable, but unfortunately it didn't solve the issue because then I came across with some not serializable classes in external libraries.

I wanted to give an update and also get your feedback on this. In my opinion, it's safe to continue ignoring this error - now that we know the details. Disabling spring-boot-devtools and use JRebel for example could be an option, too (#509).

BTW, when I enable detailed logging, this is the serialization error:

[com.vaadin.flow.server.VaadinSession.springServlet] for session [5F99452646988F0CD11EA64F32139A73]

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: io.skymind.pathmind.services.notificationservice.EmailNotificationService
	- field (class "io.skymind.pathmind.webapp.ui.views.login.LoginView", name: "emailNotificationService", type: "class io.skymind.pathmind.services.notificationservice.EmailNotificationService")
	- object (class "io.skymind.pathmind.webapp.ui.views.login.LoginView", io.skymind.pathmind.webapp.ui.views.login.LoginView@6f0d58ba)
	- element of array (index: 0)
	- array (class "[Ljava.lang.Object;", size: 1)
	- field (class "java.lang.invoke.SerializedLambda", name: "capturedArgs", type: "class [Ljava.lang.Object;")
	- object (class "java.lang.invoke.SerializedLambda", SerializedLambda[capturingClass=class io.skymind.pathmind.webapp.ui.views.login.LoginView, functionalInterfaceMethod=com/vaadin/flow/component/ComponentEventListener.onComponentEvent:(Lcom/vaadin/flow/component/ComponentEvent;)V, implementation=invokeSpecial io/skymind/pathmind/webapp/ui/views/login/LoginView.lambda$2:(Lcom/vaadin/flow/component/login/AbstractLogin$LoginEvent;)V, instantiatedMethodType=(Lcom/vaadin/flow/component/login/AbstractLogin$LoginEvent;)V, numCaptured=1])
	- field (class "com.vaadin.flow.component.ComponentEventBus$ListenerWrapper", name: "listener", type: "interface com.vaadin.flow.component.ComponentEventListener")
	- object (class "com.vaadin.flow.component.ComponentEventBus$ListenerWrapper", com.vaadin.flow.component.ComponentEventBus$ListenerWrapper@37ae79b9)
	- element of array (index: 2)
	- array (class "[Ljava.lang.Object;", size: 3)
	- field (class "java.lang.invoke.SerializedLambda", name: "capturedArgs", type: "class [Ljava.lang.Object;")
	- object (class "java.lang.invoke.SerializedLambda", SerializedLambda[capturingClass=class com.vaadin.flow.component.ComponentEventBus, functionalInterfaceMethod=com/vaadin/flow/dom/DomEventListener.handleEvent:(Lcom/vaadin/flow/dom/DomEvent;)V, implementation=invokeSpecial com/vaadin/flow/component/ComponentEventBus.lambda$addDomTrigger$dd1b7957$1:(Ljava/lang/Class;Lcom/vaadin/flow/component/ComponentEventBus$ListenerWrapper;Lcom/vaadin/flow/dom/DomEvent;)V, instantiatedMethodType=(Lcom/vaadin/flow/dom/DomEvent;)V, numCaptured=3])
	- field (class "com.vaadin.flow.internal.nodefeature.ElementListenerMap$DomEventListenerWrapper", name: "origin", type: "interface com.vaadin.flow.dom.DomEventListener")
	- object (class "com.vaadin.flow.internal.nodefeature.ElementListenerMap$DomEventListenerWrapper", com.vaadin.flow.internal.nodefeature.ElementListenerMap$DomEventListenerWrapper@6e72c2e0)
	- custom writeObject data (class "java.util.ArrayList")
	- object (class "java.util.ArrayList", [com.vaadin.flow.internal.nodefeature.ElementListenerMap$DomEventListenerWrapper@2c366bb, com.vaadin.flow.internal.nodefeature.ElementListenerMap$DomEventListenerWrapper@6e72c2e0])
	- custom writeObject data (class "java.util.HashMap")
	- object (class "java.util.HashMap", {login=[com.vaadin.flow.internal.nodefeature.ElementListenerMap$DomEventListenerWrapper@2c366bb, com.vaadin.flow.internal.nodefeature.ElementListenerMap$DomEventListenerWrapper@6e72c2e0], forgot-password=[com.vaadin.flow.internal.nodefeature.ElementListenerMap$DomEventListenerWrapper@6a94515f]})
	- field (class "com.vaadin.flow.internal.nodefeature.ElementListenerMap", name: "listeners", type: "interface java.util.Map")
	- object (class "com.vaadin.flow.internal.nodefeature.ElementListenerMap", com.vaadin.flow.internal.nodefeature.ElementListenerMap@4ec42837)
	- field (class "com.vaadin.flow.internal.nodefeature.ElementListenerMap$DomEventListenerWrapper", name: "listenerMap", type: "class com.vaadin.flow.internal.nodefeature.ElementListenerMap")
	- object (class "com.vaadin.flow.internal.nodefeature.ElementListenerMap$DomEventListenerWrapper", com.vaadin.flow.internal.nodefeature.ElementListenerMap$DomEventListenerWrapper@6a94515f)
	- field (class "com.vaadin.flow.component.ComponentEventBus$ListenerWrapper", name: "domRegistration", type: "interface com.vaadin.flow.dom.DomListenerRegistration")
	- object (class "com.vaadin.flow.component.ComponentEventBus$ListenerWrapper", com.vaadin.flow.component.ComponentEventBus$ListenerWrapper@1d35cc9b)
	- custom writeObject data (class "java.util.ArrayList")
	- object (class "java.util.ArrayList", [com.vaadin.flow.component.ComponentEventBus$ListenerWrapper@1d35cc9b])
	- custom writeObject data (class "java.util.HashMap")
	- object (class "java.util.HashMap", {class com.vaadin.flow.component.login.AbstractLogin$ForgotPasswordEvent=[com.vaadin.flow.component.ComponentEventBus$ListenerWrapper@1d35cc9b], class com.vaadin.flow.component.login.AbstractLogin$LoginEvent=[com.vaadin.flow.component.ComponentEventBus$ListenerWrapper@2eecb0fb, com.vaadin.flow.component.ComponentEventBus$ListenerWrapper@37ae79b9]})
	- field (class "com.vaadin.flow.component.ComponentEventBus", name: "componentEventData", type: "class java.util.HashMap")
	- object (class "com.vaadin.flow.component.ComponentEventBus", com.vaadin.flow.component.ComponentEventBus@33800d53)
	- field (class "com.vaadin.flow.component.Component", name: "eventBus", type: "class com.vaadin.flow.component.ComponentEventBus")
	- object (class "com.vaadin.flow.component.login.LoginForm", com.vaadin.flow.component.login.LoginForm@3119b2b6)
	- field (class "com.vaadin.flow.internal.nodefeature.ComponentMapping", name: "component", type: "class com.vaadin.flow.component.Component")
	- object (class "com.vaadin.flow.internal.nodefeature.ComponentMapping", com.vaadin.flow.internal.nodefeature.ComponentMapping@2e515ba)
	- element of array (index: 3)
	- array (class "[Lcom.vaadin.flow.internal.nodefeature.NodeFeature;", size: 15)
	- field (class "com.vaadin.flow.internal.StateNode", name: "features", type: "interface java.io.Serializable")
	- object (class "com.vaadin.flow.internal.StateNode", com.vaadin.flow.internal.StateNode@1ef9edf2)
	- custom writeObject data (class "java.util.HashMap")
	- object (class "java.util.HashMap", {1=com.vaadin.flow.internal.StateTree$RootNode@389eb384, 2=com.vaadin.flow.internal.StateNode@7a005aa, 3=com.vaadin.flow.internal.StateNode@20f82f, 4=com.vaadin.flow.internal.StateNode@d642a66, 5=com.vaadin.flow.internal.StateNode@34c83cb8, 6=com.vaadin.flow.internal.StateNode@3fc3f342, 7=com.vaadin.flow.internal.StateNode@71a51970, 8=com.vaadin.flow.internal.StateNode@546ac346, 9=com.vaadin.flow.internal.StateNode@1b42184a, 10=com.vaadin.flow.internal.StateNode@3ace9cca, 11=com.vaadin.flow.internal.StateNode@747a2211, 12=com.vaadin.flow.internal.StateNode@d9f7cb, 13=com.vaadin.flow.internal.StateNode@519e1677, 14=com.vaadin.flow.internal.StateNode@1b2aba1e, 15=com.vaadin.flow.internal.StateNode@5c050a53, 16=com.vaadin.flow.internal.StateNode@1ef9edf2, 17=com.vaadin.flow.internal.StateNode@6f34b95d, 18=com.vaadin.flow.internal.StateNode@6674338e, 19=com.vaadin.flow.internal.StateNode@1debfaa4, 20=com.vaadin.flow.internal.StateNode@5d95953c, 21=com.vaadin.flow.internal.StateNode@1733df52, 22=com.vaadin.flow.internal.StateNode@54d5f629, 23=com.vaadin.flow.internal.StateNode@a695af0, 24=com.vaadin.flow.internal.StateNode@24cdc42c, 25=com.vaadin.flow.internal.StateNode@7656be67, 26=com.vaadin.flow.internal.StateNode@1a58874b, 27=com.vaadin.flow.internal.StateNode@4fcc38d5, 28=com.vaadin.flow.internal.StateNode@70244dac, 29=com.vaadin.flow.internal.StateNode@55e720bf, 30=com.vaadin.flow.internal.StateNode@3a7de780, 31=com.vaadin.flow.internal.StateNode@3271b4c1, 32=com.vaadin.flow.internal.StateNode@339b9dc5, 33=com.vaadin.flow.internal.StateNode@5d0ab1ce, 34=com.vaadin.flow.internal.StateNode@5a96dc8e, 35=com.vaadin.flow.internal.StateNode@17e878d6})
	- field (class "com.vaadin.flow.internal.StateTree", name: "idToNode", type: "interface java.util.Map")
	- object (class "com.vaadin.flow.internal.StateTree", com.vaadin.flow.internal.StateTree@12a5ee0)
	- field (class "com.vaadin.flow.internal.StateNode", name: "owner", type: "interface com.vaadin.flow.internal.NodeOwner")
	- object (class "com.vaadin.flow.internal.StateNode", com.vaadin.flow.internal.StateNode@339b9dc5)
	- custom writeObject data (class "java.util.ArrayList")
	- object (class "java.util.ArrayList", [com.vaadin.flow.internal.StateNode@339b9dc5])
	- field (class "com.vaadin.flow.internal.nodefeature.NodeList", name: "values", type: "interface java.util.List")
	- object (class "com.vaadin.flow.internal.nodefeature.ElementChildrenList", com.vaadin.flow.internal.nodefeature.ElementChildrenList@16e4e5f6)
	- element of array (index: 1)
	- array (class "[Lcom.vaadin.flow.internal.nodefeature.NodeFeature;", size: 15)
	- field (class "com.vaadin.flow.internal.StateNode", name: "features", type: "interface java.io.Serializable")
	- object (class "com.vaadin.flow.internal.StateNode", com.vaadin.flow.internal.StateNode@5d0ab1ce)
	- custom writeObject data (class "java.util.ArrayList")
	- object (class "java.util.ArrayList", [com.vaadin.flow.internal.StateNode@5d0ab1ce, com.vaadin.flow.internal.StateNode@3271b4c1, com.vaadin.flow.internal.StateNode@3a7de780, com.vaadin.flow.internal.StateNode@5c050a53])
	- field (class "com.vaadin.flow.internal.nodefeature.NodeList", name: "values", type: "interface java.util.List")
	- object (class "com.vaadin.flow.internal.nodefeature.ElementChildrenList", com.vaadin.flow.internal.nodefeature.ElementChildrenList@212d5c17)
	- element of array (index: 1)
	- array (class "[Lcom.vaadin.flow.internal.nodefeature.NodeFeature;", size: 15)
	- field (class "com.vaadin.flow.internal.StateNode", name: "features", type: "interface java.io.Serializable")
	- object (class "com.vaadin.flow.internal.StateNode", com.vaadin.flow.internal.StateNode@5a96dc8e)
	- custom writeObject data (class "java.util.ArrayList")
	- object (class "java.util.ArrayList", [com.vaadin.flow.internal.StateNode@5a96dc8e, com.vaadin.flow.internal.StateNode@d642a66])
	- field (class "com.vaadin.flow.internal.nodefeature.NodeList", name: "values", type: "interface java.util.List")
	- object (class "com.vaadin.flow.internal.nodefeature.ElementChildrenList", com.vaadin.flow.internal.nodefeature.ElementChildrenList@3045c875)
	- element of array (index: 1)
	- array (class "[Lcom.vaadin.flow.internal.nodefeature.NodeFeature;", size: 15)
	- field (class "com.vaadin.flow.internal.StateNode", name: "features", type: "interface java.io.Serializable")
	- object (class "com.vaadin.flow.internal.StateNode", com.vaadin.flow.internal.StateNode@17e878d6)
	- custom writeObject data (class "java.util.ArrayList")
	- object (class "java.util.ArrayList", [com.vaadin.flow.internal.StateNode@17e878d6])
	- field (class "com.vaadin.flow.internal.nodefeature.NodeList", name: "values", type: "interface java.util.List")
	- object (class "com.vaadin.flow.internal.nodefeature.ElementChildrenList", com.vaadin.flow.internal.nodefeature.ElementChildrenList@59b69c96)
	- element of array (index: 1)
	- array (class "[Lcom.vaadin.flow.internal.nodefeature.NodeFeature;", size: 18)
	- field (class "com.vaadin.flow.internal.StateNode", name: "features", type: "interface java.io.Serializable")
	- object (class "com.vaadin.flow.internal.StateTree$RootNode", com.vaadin.flow.internal.StateTree$RootNode@389eb384)
	- field (class "com.vaadin.flow.dom.Node", name: "node", type: "class com.vaadin.flow.internal.StateNode")
	- object (class "com.vaadin.flow.dom.Element", <body>
 <vaadin-horizontal-layout class="login-panel-cont">
  <div class="content">
   <span class="welcome-text">Welcome to</span>
   <img alt="Pathmind logo" src="frontend/images/pathmind-logo.png" style="width:200px" class="logo">
   <div class="inner-content">
    <h3>Sign In</h3>
    <div class="error-message">
     <span>Incorrect username or password</span>
    </div>
    <vaadin-horizontal-layout style="width:100%" class="email-not-verified-cont error-message">
     <span>Email is not verified</span>
     <vaadin-button title="Send verification email again.">
      Resend
     </vaadin-button>
    </vaadin-horizontal-layout>
    <div class="info-message">
     <span>Your session expired</span>
    </div>
    <vaadin-login-form></vaadin-login-form>
   </div>
   <div class="policy">
    <span>By clicking Sign In, you agree to Pathmind's </span>
    <a href="https://pathmind.com/subscription-agreement" target="_blank">Terms of Use</a>
    <span> and </span>
    <a href="https://pathmind.com/privacy" target="_blank">Privacy Policy</a>
    <span>.</span>
   </div>
  </div>
  <segment-integrator></segment-integrator>
 </vaadin-horizontal-layout>
</body>)
	- field (class "com.vaadin.flow.component.Component", name: "element", type: "class com.vaadin.flow.dom.Element")
	- object (class "com.vaadin.flow.component.UI", com.vaadin.flow.component.UI@c5192f)
	- custom writeObject data (class "java.util.HashMap")
	- object (class "java.util.HashMap", {0=com.vaadin.flow.component.UI@c5192f, 1=com.vaadin.flow.component.UI@765d15c6})
	- field (class "com.vaadin.flow.server.VaadinSession", name: "uIs", type: "interface java.util.Map")
	- root object (class "com.vaadin.flow.spring.SpringVaadinSession", com.vaadin.flow.spring.SpringVaadinSession@733f3948)

@FollowSteph
Copy link
Contributor Author

@brunovianarezende can we also disable it in spring-boot-devtools or would that cause other issues? My main concern is that if we learn to ignore an error message like that if another much more relevant message appears we'll be so use to ignoring messages at startup that we could miss it for some time. By the way I agree trying to make everything serializable is not feasible.

@onuridrisoglu
Copy link
Contributor

Yes, session persistent can be disabled. In this case, you will need to login again every time you make some code changes. I disabled it in dev-160-disable-session-persistent branch, if you want to give it a try.

@onuridrisoglu
Copy link
Contributor

@FollowSteph now that we know more about this error message, how do you think we should proceed? I think, the alternatives are,

  • Ignore the error message
  • Disable session persistent
  • Find another solution that would replace dev-tools

@FollowSteph
Copy link
Contributor Author

@onuridrisoglu Personally I'm of the opinion that we should disable session persistence as it will only require a re-login when there is a code change. That's actually a good thing in my opinion in case something stored in the session causes a conflict with whatever has changed in the code. In other words whenever we deploy new code changes I'm ok with losing the session persistence and requiring a re-login, in fact I think it's a good thing.

That being said I think this is a decision for @slinlee so can you please confirm which you of the 3 options you want to move forward with. I'm recommending option 2 for the above reasons but there may be other factors to consider beyond just technical reasons.

@slinlee
Copy link
Contributor

slinlee commented May 30, 2020

@onuridrisoglu @FollowSteph @fionnachan @kepricon @brunovianarezende @gruff4l0 @henrikerola

I'd like your opinions:

This relates to developer experience. I tend to agree that if we regularly have error messages, we start to ignore them, esp n+1 error messages.

But at the same time, would it be annoying to you to have to log in each time after code changes in your current workflows? I personally use a very brute force workflow where I restart my server, so I'm not a good representation. I"m just testing your PR and not doing actual dev.

And regarding the third option, should we switch to using jrebel as a team? I think the Vaadin folks have experience using it, is it something you'd recommend?

@FollowSteph
Copy link
Contributor Author

Personally I recommend just re-login in every time. I too restart my server often. It's very quick and clean and guarantees the same results. And most web browsers these days will save your username and password so you just need to click on the Login button and not actually type in anything. Our app is not overly complex so re-navigating to any one screen is pretty quick.

I know some people really like JRebel but I'm personally not a big fan. I've tried it before more than once and I've found it both hard to configure/setup (outside of a very simple project and some luck) and that it has weird random issues that can eat up more time then it saves you. As in losing more time chasing a bug that was due to JRebel that eventually cost more than all the time it saved on the server reboots. My understanding is that it's more valuable when the server startup times are long, which isn't the case for us. My server startup times are within seconds, even with logging in. It could just be my experience but as a result I've not been a big fan of it.

That being said I haven't looked at it for at least 2-3 years so a lot could've changed since then. The reviews seem to be that you either love or hate it, there's very little in the middle from what I could tell the last time I looked into them. Again the slower the startup times of your application the bigger the benefit which seems to be correlated with more positive reviews. But again my experience with it is very limited to the odd trials every 1-3 years as I give it another try.

@fionnachan
Copy link
Contributor

Agree with Steph. With the browser autofill function, it's just one click every time. It doesn't take much time for now. I think if it is taking up a long time in the future, we can consider options like JRebel or other tools. But now it's not a problem.

@henrikerola
Copy link
Contributor

I like JRebel a lot but agree that it has some issues. Vaadin is also working on improving the developer experience with all these tools (JRebel, spring dev tools and also we are looking into using a special JDK + agent combination which applies code changes without restarts). But I don't think those will land to 14.x series.

Personally I would like to see a way to disable spring-dev-tools. I just comment it out right now in order to use JRebel.

Also, one option to improve login experience while developing would be to have properties to set username and password and those would be populated to username and password fields (even we could do autologin if wanted).

@FollowSteph
Copy link
Contributor Author

I just realized this ticket hasn't been updated in about a month therefore I'm following up. Basically my main concern is that over time we'll get complacent to exceptions on startup and may not notice additional ones due to being so use to this one. That being said I'm ok with losing session persistence but it's obviously your decision @slinlee. At this point since no one has really commented either way I think that should be ok. I would however recommend pushing using JRebel to another ticket if we want to pursue it further just so we can close this ticket. Again I'll leave that up to you @slinlee. I'm mainly focused on closing tech debt tickets tonight.

@slinlee
Copy link
Contributor

slinlee commented Jul 1, 2020

@FollowSteph okay, yeah, I had do re-read all of this to remember what we were talking about, but I think it makes sense to disable session persistence.

I'll assign this ticket to you to implement. @FollowSteph

@slinlee slinlee assigned FollowSteph and unassigned onuridrisoglu Jul 1, 2020
@slinlee slinlee moved this from Bugs to Rework/Revisited in Pathmind Jul 1, 2020
@stale
Copy link

stale bot commented Aug 30, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Aug 30, 2020
@slinlee
Copy link
Contributor

slinlee commented Sep 5, 2020

ping.

@stale stale bot removed the wontfix label Sep 5, 2020
@FollowSteph
Copy link
Contributor Author

@brunovianarezende Do you remember how session persistence is setup? I believe it was either you or Onur that had set it up so it might be quicker and easier for you to do adjust it. If you don't I can look into it, but if you do please let me know.

@brunovianarezende
Copy link
Contributor

@FollowSteph : no, I don't remember. Actually, I haven't touched this part of the application, if I remember correctly. I think it would be better if you could look at it.

@FollowSteph
Copy link
Contributor Author

Ok. No worries. It's not the highest priority anyways. Thanks for confirming.

@alethander
Copy link
Contributor

For some reason, I have missed that one for a long period of time.

I have two questions:

  • Did it ever affect production? Hopefully no, and we do not have dev-tools enabled in prod, do we?
  • Do dev-tools really have a positive impact on developer experience. Maybe when the developer deals with UI but had never felt the need to have dev-tools enabled. Maybe I was just lucky enough and boot up did not take crazy long. So, maybe we can exclude dev-tools out.
  • Can we live with no session persisted? If so, let's disable this feature as well.

@FollowSteph
Copy link
Contributor Author

To answer your questions:

  • Did it ever affect production? Hopefully no, and we do not have dev-tools enabled in prod, do we?

I do not believe so. @slinlee can you please confirm.

  • Do dev-tools really have a positive impact on developer experience. Maybe when the developer deals with UI but had never felt the need to have dev-tools enabled. Maybe I was just lucky enough and boot up did not take crazy long. So, maybe we can exclude dev-tools out.

I personally don't rely on them. I've had reliability issues in the past. And if I'm creating a new page or something along those lines I just temporarily add some bootstrapping code to speed up the process. But even then I find I rarely need to do this because it's often not worth it since the server startup time is fast enough.

  • Can we live with no session persisted? If so, let's disable this feature as well.

I prefer this option as well, my thinking is that it should happen very rarely for users whereas it will happen all the time for developers. However since it's a pretty subjective usability decision I would defer to @slinlee for the final call on this one.

@slinlee
Copy link
Contributor

slinlee commented Sep 17, 2020

Yes, the decision was made to disable session persistence. Here is the code you can try it out to see if it gets rid of the error @FollowSteph @alexamakarov

#160 (comment)

@FollowSteph
Copy link
Contributor Author

Thank you for confirming @slinlee Now it's just a matter of making the adjustment. On a side note I've marked it as low priority (I'm assuming that's ok @slinlee) since we've been living with it for months. The reason we want to fix it is to avoid us getting so use to seeing an exception on server startup that we miss a real exception. But since none of us remember the details I think we can push it back until we do another big cycle of tech debt. Again that is unless someone remembers.

The key based on Onur's earlier comment is that we have to figure out how to disable it in spring-dev-tools since it's set by default. That or remove spring-dev-tools which is probably a bigger decision that I would postpone for now. In my view it's either going to be very simple or someone has to dig through documentation to find where where the setting is located.

@slinlee slinlee linked a pull request Sep 21, 2020 that will close this issue
@slinlee
Copy link
Contributor

slinlee commented Sep 21, 2020

The comment from Onur included the fix, so I just rebased it and created the new PR #2125

@slinlee slinlee assigned slinlee and unassigned FollowSteph Sep 21, 2020
@slinlee slinlee moved this from Rework/Revisited to Review in progress in Pathmind Sep 21, 2020
Pathmind automation moved this from Review in progress to Released to Dev Sep 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Pathmind
  
Released to Dev
Development

Successfully merging a pull request may close this issue.

8 participants