Author: markt Date: Mon Sep 21 15:23:18 2015 New Revision: 1704318 URL: http://svn.apache.org/viewvc?rev=1704318&view=rev Log: Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=58284 Correctly implement session serialization so non-serializable attributes are skipped with a warning. Patch provided by Andrew Shore.
Modified: tomcat/trunk/java/org/apache/catalina/ha/session/DeltaSession.java tomcat/trunk/java/org/apache/catalina/session/StandardSession.java tomcat/trunk/test/org/apache/catalina/session/TestStandardSession.java Modified: tomcat/trunk/java/org/apache/catalina/ha/session/DeltaSession.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ha/session/DeltaSession.java?rev=1704318&r1=1704317&r2=1704318&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/ha/session/DeltaSession.java (original) +++ tomcat/trunk/java/org/apache/catalina/ha/session/DeltaSession.java Mon Sep 21 15:23:18 2015 @@ -24,6 +24,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.Serializable; +import java.io.WriteAbortedException; import java.security.Principal; import java.util.ArrayList; import java.util.Hashtable; @@ -771,9 +772,16 @@ public class DeltaSession extends Standa isValid = true; for (int i = 0; i < n; i++) { String name = (String) stream.readObject(); - Object value = stream.readObject(); - if ( (value instanceof String) && (value.equals(NOT_SERIALIZED))) - continue; + final Object value; + try { + value = stream.readObject(); + } catch (WriteAbortedException wae) { + if (wae.getCause() instanceof NotSerializableException) { + // Skip non serializable attributes + continue; + } + throw wae; + } attributes.put(name, value); } isValid = isValidSave; @@ -871,9 +879,7 @@ public class DeltaSession extends Standa try { stream.writeObject(saveValues.get(i)); } catch (NotSerializableException e) { - log.error(sm.getString("standardSession.notSerializable",saveNames.get(i), id), e); - stream.writeObject(NOT_SERIALIZED); - log.error(" storing attribute '" + saveNames.get(i)+ "' with value NOT_SERIALIZED"); + log.error(sm.getString("standardSession.notSerializable", saveNames.get(i), id), e); } } Modified: tomcat/trunk/java/org/apache/catalina/session/StandardSession.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/session/StandardSession.java?rev=1704318&r1=1704317&r2=1704318&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/session/StandardSession.java (original) +++ tomcat/trunk/java/org/apache/catalina/session/StandardSession.java Mon Sep 21 15:23:18 2015 @@ -22,6 +22,7 @@ import java.io.NotSerializableException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; +import java.io.WriteAbortedException; import java.security.AccessController; import java.security.Principal; import java.security.PrivilegedAction; @@ -141,14 +142,6 @@ public class StandardSession implements /** - * The dummy attribute value serialized when a NotSerializableException is - * encountered in <code>writeObject()</code>. - */ - protected static final String NOT_SERIALIZED = - "___NOT_SERIALIZABLE_EXCEPTION___"; - - - /** * The collection of user data attributes associated with this Session. */ protected Map<String, Object> attributes = new ConcurrentHashMap<>(); @@ -1631,9 +1624,16 @@ public class StandardSession implements isValid = true; for (int i = 0; i < n; i++) { String name = (String) stream.readObject(); - Object value = stream.readObject(); - if ((value instanceof String) && (value.equals(NOT_SERIALIZED))) - continue; + final Object value; + try { + value = stream.readObject(); + } catch (WriteAbortedException wae) { + if (wae.getCause() instanceof NotSerializableException) { + // Skip non serializable attributes + continue; + } + throw wae; + } if (manager.getContext().getLogger().isDebugEnabled()) manager.getContext().getLogger().debug(" loading attribute '" + name + "' with value '" + value + "'"); @@ -1709,18 +1709,11 @@ public class StandardSession implements try { stream.writeObject(saveValues.get(i)); if (manager.getContext().getLogger().isDebugEnabled()) - manager.getContext().getLogger().debug - (" storing attribute '" + saveNames.get(i) + - "' with value '" + saveValues.get(i) + "'"); + manager.getContext().getLogger().debug( + " storing attribute '" + saveNames.get(i) + "' with value '" + saveValues.get(i) + "'"); } catch (NotSerializableException e) { - manager.getContext().getLogger().warn - (sm.getString("standardSession.notSerializable", - saveNames.get(i), id), e); - stream.writeObject(NOT_SERIALIZED); - if (manager.getContext().getLogger().isDebugEnabled()) - manager.getContext().getLogger().debug - (" storing attribute '" + saveNames.get(i) + - "' with value NOT_SERIALIZED"); + manager.getContext().getLogger().warn( + sm.getString("standardSession.notSerializable", saveNames.get(i), id), e); } } Modified: tomcat/trunk/test/org/apache/catalina/session/TestStandardSession.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/session/TestStandardSession.java?rev=1704318&r1=1704317&r2=1704318&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/catalina/session/TestStandardSession.java (original) +++ tomcat/trunk/test/org/apache/catalina/session/TestStandardSession.java Mon Sep 21 15:23:18 2015 @@ -26,7 +26,6 @@ import java.util.HashMap; import java.util.Map; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; import org.apache.catalina.Manager; @@ -93,19 +92,29 @@ public class TestStandardSession { } + /* + * See Bug 58284 + */ @Test - @Ignore // This currently fails on de-serialization - bug 58284 - public void testSerializationComplex01() throws Exception { + public void serializeSkipsNonSerializableAttributes() throws Exception { + final String nonSerializableKey = "nonSerializable"; + final String nestedNonSerializableKey = "nestedNonSerializable"; + final String serializableKey = "serializable"; + final Object serializableValue = "foo"; StandardSession s1 = new StandardSession(TEST_MANAGER); s1.setValid(true); - Map<String,NonSerializable> value = new HashMap<>(); + Map<String, NonSerializable> value = new HashMap<>(); value.put("key", new NonSerializable()); - s1.setAttribute("attr01", value); + s1.setAttribute(nestedNonSerializableKey, value); + s1.setAttribute(serializableKey, serializableValue); + s1.setAttribute(nonSerializableKey, new NonSerializable()); StandardSession s2 = serializeThenDeserialize(s1); - validateSame(s1, s2, 0); + Assert.assertNull(s2.getAttribute(nestedNonSerializableKey)); + Assert.assertNull(s2.getAttribute(nonSerializableKey)); + Assert.assertEquals(serializableValue, s2.getAttribute(serializableKey)); } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org