Clustering fails on serializing javax.security.auth.subject. See stack below. I looked a little into the Tomcat code. In ./java/org/apache/catalina/connector/Request.java on line 1752 Tomcat puts the 'javax.security.auth.subject' on the session if you use a securitymanager. This is the MemoryUser in my case I think. I must use the securitymanager because I use RMI. Is there a solution possible by making the MemoryUser serializable or by not putting it in the session as an attribute. Mark Thomas <markt_at_apache_dot_org> suggested a note on the session at the Tomcat user-mailinglist. I've never seen notes on sessions. The MemoryUser comes from the security-constraint in my web.xml. Jul 8, 2009 5:53:52 PM org.apache.catalina.ha.session.DeltaSession writeObject SEVERE: Cannot serialize session attribute javax.security.auth.subject for session 9C533E0EB4A79ED5B206B8F5A5DB09AD java.io.NotSerializableException: org.apache.catalina.users.MemoryUser at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326) at java.util.LinkedList.writeObject(LinkedList.java:943) at sun.reflect.GeneratedMethodAccessor216.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.access$300(ObjectOutputStream.java:143) at java.io.ObjectOutputStream$PutFieldImpl.writeFields(ObjectOutputStream.java:1668) at java.io.ObjectOutputStream.writeFields(ObjectOutputStream.java:454) at javax.security.auth.Subject$SecureSet.writeObject(Subject.java:1281) at sun.reflect.GeneratedMethodAccessor215.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:416) at java.util.Collections$SynchronizedCollection.writeObject(Collections.java:1602) at sun.reflect.GeneratedMethodAccessor214.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:416) at javax.security.auth.Subject.writeObject(Subject.java:919) at sun.reflect.GeneratedMethodAccessor213.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326) at org.apache.catalina.ha.session.DeltaSession.writeObject(DeltaSession.java:714) at org.apache.catalina.ha.session.DeltaSession.writeObjectData(DeltaSession.java:475) at org.apache.catalina.ha.session.DeltaSession.writeObjectData(DeltaSession.java:472) at org.apache.catalina.ha.session.DeltaManager.serializeSessions(DeltaManager.java:733) at org.apache.catalina.ha.session.DeltaManager.sendSessions(DeltaManager.java:1513) at org.apache.catalina.ha.session.DeltaManager.handleGET_ALL_SESSIONS(DeltaManager.java:1479) at org.apache.catalina.ha.session.DeltaManager.messageReceived(DeltaManager.java:1310) at org.apache.catalina.ha.session.DeltaManager.messageDataReceived(DeltaManager.java:1093) at org.apache.catalina.ha.session.ClusterSessionListener.messageReceived(ClusterSessionListener.java:87) at org.apache.catalina.ha.tcp.SimpleTcpCluster.messageReceived(SimpleTcpCluster.java:901) at org.apache.catalina.ha.tcp.SimpleTcpCluster.messageReceived(SimpleTcpCluster.java:882) at org.apache.catalina.tribes.group.GroupChannel.messageReceived(GroupChannel.java:269) at org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:79) at org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:79) at org.apache.catalina.tribes.group.interceptors.TcpFailureDetector.messageReceived(TcpFailureDetector.java:110) at org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:79) at org.apache.catalina.tribes.group.ChannelCoordinator.messageReceived(ChannelCoordinator.java:241) at org.apache.catalina.tribes.transport.ReceiverBase.messageDataReceived(ReceiverBase.java:225) at org.apache.catalina.tribes.transport.nio.NioReplicationTask.drainChannel(NioReplicationTask.java:188) at org.apache.catalina.tribes.transport.nio.NioReplicationTask.run(NioReplicationTask.java:91) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619)
StandardSession excludes the session attribute named javax.security.auth.subject from being serialized. DeltaSession does not. Here's what StandardSession excludes from serializing: protected static final String[] excludedAttributes = { Globals.SUBJECT_ATTR }; Of course ... I suspect (without a deeper code dive) that excluding this from serialization might mean that you are not logged in across the whole cluster. How to test ... Here is the existing code in DeltaSession.writeObject for (int i = 0; i < keys.length; i++) { Object value = null; value = attributes.get(keys[i]); if (value == null) continue; else if (value instanceof Serializable) { saveNames.add(keys[i]); saveValues.add(value); } } try changing it to (so we are excluding it from serialization) for (int i = 0; i < keys.length; i++) { Object value = null; value = attributes.get(keys[i]); if (value == null || exclude(keys[i])) continue; else if (value instanceof Serializable) { saveNames.add(keys[i]); saveValues.add(value); } } HERE is the patch ... Index: java/org/apache/catalina/ha/session/DeltaSession.java =================================================================== --- java/org/apache/catalina/ha/session/DeltaSession.java (revision 833086) +++ java/org/apache/catalina/ha/session/DeltaSession.java (working copy) @@ -731,7 +731,7 @@ for (int i = 0; i < keys.length; i++) { Object value = null; value = attributes.get(keys[i]); - if (value == null) + if (value == null || exclude(keys[i])) continue; else if (value instanceof Serializable) { saveNames.add(keys[i]);
changing status to NEEDINFO based on last comment
This session attribute used when running under a security manager. Authentication is handled separately. The patch looks good to me. I've applied it to trunk and proposed it for 6.0.x
This has been fixed in 6.0.x and will be included in 6.0.21 onwards.