Bug 50950

Summary: NotSerializableException: org.apache.catalina.realm.GenericPrincipal
Product: Tomcat 6 Reporter: Ronald Klop <ronald>
Component: ClusterAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 6.0.32   
Target Milestone: default   
Hardware: Other   
OS: Linux   
Attachments: server.xml and context to reproduce the issue
full stacktrace
zip with content (logs/web dir/conf)

Description Ronald Klop 2011-03-20 13:28:18 UTC
Because this issue (https://issues.apache.org/bugzilla/show_bug.cgi?id=47502) is fixed I re-enabled using the security-constraint in web.xml to protect some pages instead of using my own workaround. But now I get a somewhat similar exception.

This is running Tomcat 6.0.32 (directly from your tar.gz) on Debian 5 in a cluster of 3 nodes.
I access my password protected pages over https.

 Mar 11, 2011 1:20:48 PM org.apache.catalina.ha.session.DeltaManager requestCompleted
 SEVERE: Unable to serialize delta request for sessionid [7D6D6A80C080C132F7EDCDAA3DFCEFB7]
 java.io.NotSerializableException: org.apache.catalina.realm.GenericPrincipal
     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
     at java.util.LinkedList.writeObject(LinkedList.java:943)
     at sun.reflect.GeneratedMethodAccessor65.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:1469)
     at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
     at java.io.ObjectOutputStream.access$300(ObjectOutputStream.java:143)
     at java.io.ObjectOutputStream$PutFieldImpl.writeFields(ObjectOutputStream.java:1677)
     at java.io.ObjectOutputStream.writeFields(ObjectOutputStream.java:462)
     at javax.security.auth.Subject$SecureSet.writeObject(Subject.java:1281)
     at sun.reflect.GeneratedMethodAccessor64.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:1469)
     at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
     at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
     at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:422)
     at java.util.Collections$SynchronizedCollection.writeObject(Collections.java:1602)
     at sun.reflect.GeneratedMethodAccessor63.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:1469)
Comment 1 Mark Thomas 2011-03-21 17:27:19 UTC
I can't reproduce this issue. Additionally:
- GenericPrincipal should always be converted to SerializablePrincipal by Tomcat (I can;t see anywhere it isn't)
- The stack trace provided below is incomplete

If you re-open this issue you will need to provide information necessary to reproduce this issue from a clean install of the latest Tomcat 6.0.x release.
Comment 2 Ronald Klop 2011-03-25 12:51:55 UTC
Created attachment 26798 [details]
server.xml and context to reproduce the issue

If you set up a cluster and ask for /index.jsp than it is ok.
If you ask for /intern/index.jsp (behind a password) than you get serialization exceptions.
As far as I see, there is no other Realm type which is serializable.
Why is this object on the session anyway?

Mar 25, 2011 5:35:17 PM org.apache.catalina.ha.session.DeltaManager requestCompleted
SEVERE: Unable to serialize delta request for sessionid [F9D61003F2344ED314504FDE3BDF9FDA]
java.io.NotSerializableException: org.apache.catalina.realm.GenericPrincipal
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
        at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
        at java.util.LinkedList.writeObject(LinkedList.java:960)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
Comment 3 Ronald Klop 2011-03-25 12:53:38 UTC
You asked for the complete stack.
Mar 25, 2011 5:35:17 PM org.apache.catalina.ha.session.DeltaManager requestCompleted
SEVERE: Unable to serialize delta request for sessionid [F9D61003F2344ED314504FDE3BDF9FDA]
java.io.NotSerializableException: org.apache.catalina.realm.GenericPrincipal
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
        at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
        at java.util.LinkedList.writeObject(LinkedList.java:960)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:616)
        at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
        at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
        at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
        at java.io.ObjectOutputStream.access$300(ObjectOutputStream.java:161)
        at java.io.ObjectOutputStream$PutFieldImpl.writeFields(ObjectOutputStream.java:1687)
        at java.io.ObjectOutputStream.writeFields(ObjectOutputStream.java:478)
        at javax.security.auth.Subject$SecureSet.writeObject(Subject.java:1300)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:616)
        at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
        at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
        at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
        at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
        at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:438)
Comment 4 Konstantin Kolinko 2011-03-25 18:45:16 UTC
(In reply to comment #3)
> You asked for the complete stack.

The stack trace is still incomplete. What calls the last line in your comment (below)? - where the ObjectOutputStream is called from?

>(...)
> java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:438)

Note, that is is not necessary to paste the stacktrace as a comment:
you can attach it as a file.
Comment 5 Ronald Klop 2011-03-28 03:09:58 UTC
Created attachment 26803 [details]
full stacktrace

Mmm, my (new) terminal doesn't copy what is outside the viewport. Now you have a complete stack.
Comment 6 Mark Thomas 2011-05-05 10:31:40 UTC
The attached test case is just an empty zip. Not helpful.

Failing to mention that this only occurs when running a security manager and that the stack trace appears on session expiration was also not helpful. 

Fortunately, there were enough clues in the stacktrace to figure out what was going on and I can now reproduce this. I'm currently working on a fix.
Comment 7 Mark Thomas 2011-05-05 12:46:36 UTC
This is fixed in 7.0.x and will be included in 7.0.13 onwards.

It looks like back-porting the 7.0.x will be insufficient to address all the issues in 6.0.x. I'm working on a 6.0.x patch.
Comment 8 Mark Thomas 2011-05-05 13:23:42 UTC
Hmm. The reproduction steps that worked on Tomcat 7, don't on Tomcat 6.

Please provide the steps and configuration necessary to reproduce this on the latest Tomcat 6 source. Without steps to reproduce, this will eventually get resolved as WORKSFORME.
Comment 9 Ronald Klop 2011-05-09 16:04:45 UTC
Created attachment 26979 [details]
zip with content (logs/web dir/conf)

Hi, in the attachment more content hopefully. I must be a dumb-ass to upload an empty zip.
Indeed I use the security manager, because my app uses rmi. Didn't mention it, because I run it for years already and didn't think about it.

In the zip is a context. I use 'pen -fr 8080 localhost:8081 localhost:8082' as a loadbalancer and 'connection: close' for this test, so requests go round robin.
If you go to / (or /index.jsp) you get a session and all is well. If you than go to /intern/ you get an exception as is seen in catalina.out.node-b.

This is on 6.0.32 as you can see in the logs.

I hope I have provided better info this time. Thanks for looking into this.
Comment 10 Mark Thomas 2011-05-09 17:15:18 UTC
Thanks. That did it. The fix is the same in 6 as it was in 7. I have proposed the patch.
Comment 11 Mark Thomas 2011-05-10 08:36:25 UTC
Fixed in 6.0.x and will be included in 6.0.33 onwards.