Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 328306

Summary: Session Clustering with Database and FORM Authentication Broken
Product: [RT] Jetty Reporter: Michael Malamud <mike.malamud>
Component: serverAssignee: Greg Wilkins <gregw>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: janb, jesse.mcconnell, jetty-inbox, mike.malamud
Version: 7.1.3   
Target Milestone: 7.1.x   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Bug Depends on:    
Bug Blocks: 328273    

Description Michael Malamud CLA 2010-10-20 20:55:45 EDT
Build Identifier: jetty/7.1.3.v20100526

I am currently trying to implement session clustering with a database using JDBC as described in the following link:

http://docs.codehaus.org/display/JETTY/Session+Clustering+with+a+Database

I have been able to successfully get this working.

In order for this to work, all object stored in the session must obey the Serialization contract. 

The problem is that I am also using FORM authentication and JAAS, and there is a class built into Jetty (org.eclipse.jetty.security.authentication.SessionAuthentication),
that does not implement the Serializable interface, and as a result, I am getting the following exception:

2010-10-08 15:31:35.230:WARN::Problem persisting changed session data id=uca15k7lm9p51mh2l82kdi2tvcmw
java.io.NotSerializableException: org.eclipse.jetty.server.session.JDBCSessionManager

Digging deeper I was able to determine that it is the org.eclipse.jetty.security.authentication.SessionAuthentication class that was causing the exception to be thrown. 

It occurs after login when the org.eclipse.jetty.security.UserIdentity attribute is attempted to be added to the session.


Reproducible: Always

Steps to Reproduce:
1. Enable form-based authentication using JAAS
2. Enable session clustering using a database
3. After logging in, you will get the java.io.NotSerializableException when org.eclipse.jetty.security.UserIdentity is attempted to be added to the session.
Comment 1 Greg Wilkins CLA 2010-10-21 06:17:41 EDT
I have updated the SessionAuthentication so that it the non serializable bits are transient.  They are reestablished when the auth is deserialized.

The test harnesses are not great for this part of the code. so it would be great if you could try a build after r2381.

Also I'm uploading a build to 
http://oss.sonatype.org/content/repositories/jetty-snapshots/org/eclipse/jetty/jetty-distribution/7.2.1-SNAPSHOT
Comment 2 Michael Malamud CLA 2010-10-22 15:12:09 EDT
This fix seems to have resolved the NotSerializable exception. 

I have witnessed the following behavior however:

If I leave my system idle for a few hours, when I come back I see the following exception in the console window:

2010-10-22 11:03:44.342:WARN::Unable to load session from database
java.lang.IllegalStateException: !SecurityHandler
	at org.eclipse.jetty.security.authentication.SessionAuthentication.readObject(SessionAuthentication.java:83)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
	at java.io.ObjectInputStream.readSerialData(Unknown Source)
	at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
	at java.io.ObjectInputStream.readObject0(Unknown Source)
	at java.io.ObjectInputStream.readObject(Unknown Source)
	at java.util.concurrent.ConcurrentHashMap.readObject(Unknown Source)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
	at java.io.ObjectInputStream.readSerialData(Unknown Source)
	at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
	at java.io.ObjectInputStream.readObject0(Unknown Source)
	at java.io.ObjectInputStream.readObject(Unknown Source)
	at org.eclipse.jetty.server.session.JDBCSessionManager.loadSession(JDBCSessionManager.java:866)
	at org.eclipse.jetty.server.session.JDBCSessionManager.getSession(JDBCSessionManager.java:504)
	at org.eclipse.jetty.server.session.JDBCSessionManager.removeSession(JDBCSessionManager.java:728)
	at org.eclipse.jetty.server.session.AbstractSessionManager$Session.timeout(AbstractSessionManager.java:1039)
	at org.eclipse.jetty.server.session.JDBCSessionManager$Session.timeout(JDBCSessionManager.java:363)
	at org.eclipse.jetty.server.session.JDBCSessionManager.expire(JDBCSessionManager.java:784)
	at org.eclipse.jetty.server.session.JDBCSessionIdManager.scavenge(JDBCSessionIdManager.java:682)
	at org.eclipse.jetty.server.session.JDBCSessionIdManager.access$000(JDBCSessionIdManager.java:53)
	at org.eclipse.jetty.server.session.JDBCSessionIdManager$1.run(JDBCSessionIdManager.java:243)
	at java.util.TimerThread.mainLoop(Unknown Source)
	at java.util.TimerThread.run(Unknown Source)
Comment 3 Jan Bartel CLA 2010-10-22 21:15:56 EDT
When the scavenge happens, there will be no current SecurityHandler, as no Context is in scope.

We will need to rethink that logic. Possibly also the logic on the JDBC scavenge, as we are loading the session only in order to delete it - might make more sense to just delete it directly from the database in this case.

Jan
Comment 4 Greg Wilkins CLA 2010-10-22 21:28:03 EDT
The JDBC load session is now called in the scope of a context handler
Comment 5 Michael Malamud CLA 2010-11-02 10:15:08 EDT
In what version can I find the latest fixes for this issue?
Comment 7 Michael Malamud CLA 2010-11-02 15:11:48 EDT
I just downloaded that package and noticed that after I unzipped it, in the /lib directory there are double .jar files for most of the jetty jars.

I am seeing:

jetty-ajp-7.2.0.v20101020.jar
jetty-ajp-7.2.1-SNAPSHOT.jar

jetty-annotations-7.2.0.v20101020.jar
jetty-annotations-7.2.1-SNAPSHOT.jar


etc...


Should they both be there or only the jars ending with "-7.2.1-SNAPSHOT.jar"


Thanks...
Comment 9 Michael Malamud CLA 2010-11-09 17:59:48 EST
I am now seeing the following exception every couple of minutes or so:

09 Nov 2010 17:51:31.986 [qtp16821027-14] DEBUG org.eclipse.jetty.util.log - EOF
org.eclipse.jetty.io.EofException: null
	at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:319) ~[jetty-http-7.2.1-SNAPSHOT.jar:7.2.1-SNAPSHOT]
	at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:212) ~[jetty-http-7.2.1-SNAPSHOT.jar:7.2.1-SNAPSHOT]
	at org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:426) ~[jetty-server-7.2.1-SNAPSHOT.jar:7.2.1-SNAPSHOT]
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:510) [jetty-io-7.2.1-SNAPSHOT.jar:7.2.1-SNAPSHOT]
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint.access$000(SelectChannelEndPoint.java:34) [jetty-io-7.2.1-SNAPSHOT.jar:7.2.1-SNAPSHOT]
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40) [jetty-io-7.2.1-SNAPSHOT.jar:7.2.1-SNAPSHOT]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:450) [jetty-util-7.2.1-SNAPSHOT.jar:7.2.1-SNAPSHOT]
	at java.lang.Thread.run(Unknown Source) [na:1.6.0_20]



I am not sure what is causing this nor can I really debug much here...
Comment 10 Greg Wilkins CLA 2010-11-09 22:48:45 EST
Michael,

I think that might just be the normal EOF exception thrown when a client times out an idle connection and closes it.  You are only seeing it because debug is turned on.