Uploaded image for project: 'PUBLIC - Liferay Portal Community Edition'
  1. PUBLIC - Liferay Portal Community Edition
  2. LPS-73732

In case of having a tomcat cluster with session replication, java.lang.ClassNotFoundException is thrown during startup or shutdown of one cluster node

    Details

      Description

      In case of having a tomcat cluster with session replication, java.lang.ClassNotFoundException is thrown during startup or shutdown of one cluster node because osgi modules are not available but second node is sending session replication data referring to that non-existant osgi module.

      The same error is reproduced in case of connecting to gogo console and manually stopping/starting related module in only one cluster node and making http request to the other node (easier to reproduce)

      Environment setup

      1. Configure Liferay cluster with two tomcat nodes, see instructions in LPS-72500
      2. Add portlet.session.replicate.enabled=true in portal-ext.properties (created in LPS-72911)

      Steps to reproduce: stopping osgi module (easy way)

      1. Start first tomcat node and wait until startup finish
      2. Verify you can login from browser using URL: http://localhost:8080/web/guest
      3. Install attached test-session-replication-portlet.war in first tomcat node (copy war to liferay deploy directory)
      4. Create a page called "session replication test"
      5. Add test session replication portlet to created page
      6. Start second tomcat node and wait until startup finish
      7. Install attached test-session-replication-portlet.war in second tomcat node (copy war to liferay deploy directory)
      8. Open created page "session replication test" in a new browser using URL of first node
      9. Following message will be displayed: No sessionData exists, generated a new one with random string ....
      10. Refresh page: generated random string will be displayed again
      11. In same browser, open same page but in second node.
        • Same random string generated in first node will be displayed in second one (random string is replicated through tomcat session replication)
      12. Connect to gogo console of first node: telnet localhost <gogo console port of first node>
      13. Execute lb |grep test-session-replication-portlet
      14. Stop replication portlet module: stop <id> (id: number obtained in previous step)
      15. Now, in first node portlet will be not available
      16. Open created page "session replication test" in a new browser using URL of second node
        • Correct behavior: No error is displayed
        • Wrong behavior: Following error is displayed in some session event replication, in the opposite node
          10:11:58,847 ERROR [Tribes-Task-Receiver-1][SerializableObjectWrapper:87] Unable to deserialize object
          java.lang.ClassNotFoundException: test.session.replication.MySessionData
                  at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1308)
                  at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1142)
                  at java.lang.Class.forName0(Native Method)
                  at java.lang.Class.forName(Class.java:348)
                  at com.liferay.portal.kernel.util.ClassResolverUtil.resolve(ClassResolverUtil.java:29)
           [...]
                  at org.apache.catalina.ha.session.DeltaRequest$AttributeInfo.readExternal(DeltaRequest.java:387)
                  at org.apache.catalina.ha.session.DeltaRequest.readExternal(DeltaRequest.java:277)
                  at org.apache.catalina.ha.session.DeltaManager.deserializeDeltaRequest(DeltaManager.java:565)
                  at org.apache.catalina.ha.session.DeltaManager.handleSESSION_DELTA(DeltaManager.java:1233)
          

      Steps to reproduce: stopping a node from cluster (difficult way)

      1. Execute steps 1 to 11 of previous section
      2. Stop first node
      3. During first node shutdown, make requests to second node. Open and close browser between each request in order to generate a new session
      4. Check cluster log files:
        • Correct behavior: No error is displayed
        • Wrong behavior: Following error is displayed in some session event replication, in the opposite node
          10:11:58,847 ERROR [Tribes-Task-Receiver-1][SerializableObjectWrapper:87] Unable to deserialize object
          java.lang.ClassNotFoundException: test.session.replication.MySessionData
                  at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1308)
                  at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1142)
                  at java.lang.Class.forName0(Native Method)
                  at java.lang.Class.forName(Class.java:348)
                  at com.liferay.portal.kernel.util.ClassResolverUtil.resolve(ClassResolverUtil.java:29)
                  at com.liferay.portal.kernel.io.ProtectedAnnotatedObjectInputStream.doResolveClass(ProtectedAnnotatedObjectInputStream.java:46)
                  at com.liferay.portal.kernel.io.ProtectedObjectInputStream.resolveClass(ProtectedObjectInputStream.java:63)
                  at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1620)
                  at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)
                  at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781)
                  at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
                  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
                  at com.liferay.portal.kernel.io.Deserializer.readObject(Deserializer.java:158)
                  at com.liferay.portal.kernel.io.SerializableObjectWrapper.readExternal(SerializableObjectWrapper.java:84)
                  at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1849)
                  at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1806)
                  at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
                  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
                  at org.apache.catalina.ha.session.DeltaRequest$AttributeInfo.readExternal(DeltaRequest.java:387)
                  at org.apache.catalina.ha.session.DeltaRequest.readExternal(DeltaRequest.java:277)
                  at org.apache.catalina.ha.session.DeltaManager.deserializeDeltaRequest(DeltaManager.java:565)
                  at org.apache.catalina.ha.session.DeltaManager.handleSESSION_DELTA(DeltaManager.java:1233)
                  at org.apache.catalina.ha.session.DeltaManager.messageReceived(DeltaManager.java:1177)
                  at org.apache.catalina.ha.session.DeltaManager.messageDataReceived(DeltaManager.java:916)
                  at org.apache.catalina.ha.session.ClusterSessionListener.messageReceived(ClusterSessionListener.java:77)
                  at org.apache.catalina.ha.tcp.SimpleTcpCluster.messageReceived(SimpleTcpCluster.java:788)
                  at org.apache.catalina.ha.tcp.SimpleTcpCluster.messageReceived(SimpleTcpCluster.java:769)
                  at org.apache.catalina.tribes.group.GroupChannel.messageReceived(GroupChannel.java:296)
                  at org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:81)
                  at org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:81)
                  at org.apache.catalina.tribes.group.interceptors.TcpFailureDetector.messageReceived(TcpFailureDetector.java:117)
                  at org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:81)
                  at org.apache.catalina.tribes.group.ChannelCoordinator.messageReceived(ChannelCoordinator.java:262)
                  at org.apache.catalina.tribes.transport.ReceiverBase.messageDataReceived(ReceiverBase.java:242)
                  at org.apache.catalina.tribes.transport.nio.NioReplicationTask.drainChannel(NioReplicationTask.java:211)
                  at org.apache.catalina.tribes.transport.nio.NioReplicationTask.run(NioReplicationTask.java:102)
                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
                  at java.lang.Thread.run(Thread.java:745)
          

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                joyce.wang Joyce Wang
                Reporter:
                jorge.diaz Jorge Diaz
                Participants of an Issue:
                Recent user:
                Jason Pince
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Days since last comment:
                  1 year, 34 weeks, 6 days ago