From ad839e5693a3e718da952e18ffb2129d7817a3ff Mon Sep 17 00:00:00 2001 From: "Jonathan S. Fisher" Date: Mon, 7 Jun 2021 14:49:28 -0500 Subject: [PATCH 1/3] Fix #430 - Principal and other attributes need some flexibility with Serialization. Allow for custom serializers --- .../web/msm/DefaultObjectIOFactory.java | 8 ++ .../web/msm/DefaultObjectIOStrategy.java | 22 ++++++ .../web/msm/MemcachedSessionService.java | 50 ++++++++++--- .../javakaffee/web/msm/ObjectIOFactory.java | 5 ++ .../javakaffee/web/msm/ObjectIOStrategy.java | 13 ++++ .../javakaffee/web/msm/TranscoderService.java | 73 +++++++++++-------- .../web/msm/TranscoderServiceTest.java | 20 ++--- kryo-serializer/pom.xml | 2 +- .../msm/MemcachedBackupSessionManager.java | 8 +- .../msm/MemcachedBackupSessionManager.java | 8 +- .../msm/MemcachedBackupSessionManager.java | 8 +- .../msm/MemcachedBackupSessionManager.java | 8 +- 12 files changed, 156 insertions(+), 69 deletions(-) create mode 100644 core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOFactory.java create mode 100644 core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOStrategy.java create mode 100644 core/src/main/java/de/javakaffee/web/msm/ObjectIOFactory.java create mode 100644 core/src/main/java/de/javakaffee/web/msm/ObjectIOStrategy.java diff --git a/core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOFactory.java b/core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOFactory.java new file mode 100644 index 00000000..70dce4cb --- /dev/null +++ b/core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOFactory.java @@ -0,0 +1,8 @@ +package de.javakaffee.web.msm; + +public class DefaultObjectIOFactory implements ObjectIOFactory { + @Override + public ObjectIOStrategy createObjectIOStrategy() { + return new DefaultObjectIOStrategy(); + } +} diff --git a/core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOStrategy.java b/core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOStrategy.java new file mode 100644 index 00000000..6c52f695 --- /dev/null +++ b/core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOStrategy.java @@ -0,0 +1,22 @@ +package de.javakaffee.web.msm; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInput; +import java.io.ObjectInputStream; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.io.OutputStream; + +public class DefaultObjectIOStrategy implements ObjectIOStrategy { + + @Override + public ObjectInput createObjectInput(InputStream is) throws IOException { + return new ObjectInputStream(is); + } + + @Override + public ObjectOutput createObjectOutput(OutputStream os) throws IOException { + return new ObjectOutputStream(os); + } +} diff --git a/core/src/main/java/de/javakaffee/web/msm/MemcachedSessionService.java b/core/src/main/java/de/javakaffee/web/msm/MemcachedSessionService.java index 769207fe..da8fbda4 100644 --- a/core/src/main/java/de/javakaffee/web/msm/MemcachedSessionService.java +++ b/core/src/main/java/de/javakaffee/web/msm/MemcachedSessionService.java @@ -23,7 +23,9 @@ import static de.javakaffee.web.msm.Statistics.StatsType.SESSION_DESERIALIZATION; import java.io.IOException; +import java.io.ObjectInput; import java.io.ObjectInputStream; +import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.security.Principal; import java.util.List; @@ -160,6 +162,13 @@ static enum LockStatus { * {@link JavaSerializationTranscoderFactory}. */ private String _transcoderFactoryClassName = JavaSerializationTranscoderFactory.class.getName(); + + /** + * The class name of the factory for + * {@link net.spy.memcached.transcoders.Transcoder}s. Default class name is + * {@link JavaSerializationTranscoderFactory}. + */ + private String _objectIOFactoryClassName = DefaultObjectIOFactory.class.getName(); /** * Specifies, if iterating over collection elements shall be done on a copy @@ -222,6 +231,7 @@ static enum LockStatus { protected TranscoderService _transcoderService; private TranscoderFactory _transcoderFactory; + private ObjectIOFactory _objectIOFactory; private BackupSessionService _backupSessionService; @@ -339,7 +349,7 @@ public static interface SessionManager extends Manager { * @param oos the output stream * @throws IOException expected to be declared by the implementation. */ - void writePrincipal( @Nonnull Principal principal, @Nonnull ObjectOutputStream oos) throws IOException; + void writePrincipal( @Nonnull Principal principal, @Nonnull ObjectOutput oos) throws IOException; /** * Reads the Principal from the given OIS. @@ -349,7 +359,7 @@ public static interface SessionManager extends Manager { * @throws IOException expected to be declared by the implementation. */ @Nonnull - Principal readPrincipal( @Nonnull ObjectInputStream ois ) throws ClassNotFoundException, IOException; + Principal readPrincipal( @Nonnull ObjectInput ois ) throws ClassNotFoundException, IOException; /** * Determines if the context has a security contraint with form based login. @@ -496,7 +506,7 @@ protected MemcachedNodesManager createMemcachedNodesManager(final String memcach } private TranscoderService createTranscoderService( final Statistics statistics ) { - return new TranscoderService( getTranscoderFactory().createTranscoder( _manager ) ); + return new TranscoderService( getTranscoderFactory().createTranscoder( _manager ), getObjectIOFactory().createObjectIOStrategy() ); } protected TranscoderFactory getTranscoderFactory() { @@ -509,6 +519,17 @@ protected TranscoderFactory getTranscoderFactory() { } return _transcoderFactory; } + + protected ObjectIOFactory getObjectIOFactory() { + if ( _objectIOFactory == null ) { + try { + _objectIOFactory = createObjectIOFactory(); + } catch ( final Exception e ) { + throw new RuntimeException( "Could not create transcoder factory.", e ); + } + } + return _objectIOFactory; + } protected StorageClient createStorageClient(final MemcachedNodesManager memcachedNodesManager, final Statistics statistics ) { @@ -523,7 +544,7 @@ protected StorageClient createStorageClient(final MemcachedNodesManager memcache private TranscoderFactory createTranscoderFactory() throws InstantiationException, IllegalAccessException, ClassNotFoundException { _log.info( "Creating transcoder factory " + _transcoderFactoryClassName ); - final Class transcoderFactoryClass = loadTranscoderFactoryClass(); + final Class transcoderFactoryClass = loadFactoryClass(_transcoderFactoryClassName, _manager.getContainerClassLoader(), TranscoderFactory.class); final TranscoderFactory transcoderFactory = transcoderFactoryClass.newInstance(); transcoderFactory.setCopyCollectionsForSerialization( _copyCollectionsForSerialization ); if ( _customConverterClassNames != null ) { @@ -532,18 +553,25 @@ private TranscoderFactory createTranscoderFactory() throws InstantiationExceptio } return transcoderFactory; } + + private ObjectIOFactory createObjectIOFactory() throws InstantiationException, IllegalAccessException, ClassNotFoundException { + _log.info( "Creating objectIO factory " + _objectIOFactoryClassName ); + final Class objectIOFactoryClass = loadFactoryClass(_objectIOFactoryClassName, _manager.getContainerClassLoader(), ObjectIOFactory.class); + final ObjectIOFactory objectIOFactory = objectIOFactoryClass.newInstance(); + return objectIOFactory; + } + - private Class loadTranscoderFactoryClass() throws ClassNotFoundException { - Class transcoderFactoryClass; - final ClassLoader classLoader = _manager.getContainerClassLoader(); + private Class loadFactoryClass(String className, ClassLoader classLoader, Class factoryInterface) throws ClassNotFoundException { + Class factoryClass; try { - _log.debug( "Loading transcoder factory class " + _transcoderFactoryClassName + " using classloader " + classLoader ); - transcoderFactoryClass = Class.forName( _transcoderFactoryClassName, false, classLoader ).asSubclass( TranscoderFactory.class ); + _log.debug( "Loading transcoder factory class " + className + " using classloader " + classLoader ); + factoryClass = Class.forName( className, false, classLoader ).asSubclass(factoryInterface); } catch ( final ClassNotFoundException e ) { _log.info( "Could not load transcoderfactory class with classloader "+ classLoader +", trying " + getClass().getClassLoader() ); - transcoderFactoryClass = Class.forName( _transcoderFactoryClassName, false, getClass().getClassLoader() ).asSubclass( TranscoderFactory.class ); + factoryClass = Class.forName( className, false, getClass().getClassLoader() ).asSubclass( factoryInterface ); } - return transcoderFactoryClass; + return factoryClass; } /** diff --git a/core/src/main/java/de/javakaffee/web/msm/ObjectIOFactory.java b/core/src/main/java/de/javakaffee/web/msm/ObjectIOFactory.java new file mode 100644 index 00000000..152146b5 --- /dev/null +++ b/core/src/main/java/de/javakaffee/web/msm/ObjectIOFactory.java @@ -0,0 +1,5 @@ +package de.javakaffee.web.msm; + +public interface ObjectIOFactory { + ObjectIOStrategy createObjectIOStrategy(); +} diff --git a/core/src/main/java/de/javakaffee/web/msm/ObjectIOStrategy.java b/core/src/main/java/de/javakaffee/web/msm/ObjectIOStrategy.java new file mode 100644 index 00000000..f0d52474 --- /dev/null +++ b/core/src/main/java/de/javakaffee/web/msm/ObjectIOStrategy.java @@ -0,0 +1,13 @@ +package de.javakaffee.web.msm; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.io.OutputStream; + +public interface ObjectIOStrategy { + ObjectInput createObjectInput( InputStream is ) throws IOException; + + ObjectOutput createObjectOutput( OutputStream os ) throws IOException; +} diff --git a/core/src/main/java/de/javakaffee/web/msm/TranscoderService.java b/core/src/main/java/de/javakaffee/web/msm/TranscoderService.java index b0db00e4..db067dfe 100644 --- a/core/src/main/java/de/javakaffee/web/msm/TranscoderService.java +++ b/core/src/main/java/de/javakaffee/web/msm/TranscoderService.java @@ -18,11 +18,10 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.Closeable; import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.io.UnsupportedEncodingException; import java.security.Principal; import java.util.ArrayList; @@ -69,14 +68,26 @@ public class TranscoderService { + 8; // lastBackupTime private final SessionAttributesTranscoder _attributesTranscoder; + private final ObjectIOStrategy _objectIOStrategy; /** * Creates a new {@link TranscoderService}. * * @param attributesTranscoder the {@link SessionAttributesTranscoder} strategy to use. */ - public TranscoderService( final SessionAttributesTranscoder attributesTranscoder ) { + public TranscoderService( final SessionAttributesTranscoder attributesTranscoder) { _attributesTranscoder = attributesTranscoder; + _objectIOStrategy = new DefaultObjectIOStrategy(); + } + + /** + * Creates a new {@link TranscoderService}. + * + * @param attributesTranscoder the {@link SessionAttributesTranscoder} strategy to use. + */ + public TranscoderService( final SessionAttributesTranscoder attributesTranscoder, ObjectIOStrategy objectIOStrategy) { + _attributesTranscoder = attributesTranscoder; + _objectIOStrategy = objectIOStrategy; } /** @@ -186,11 +197,11 @@ public byte[] serialize( final MemcachedBackupSession session, final byte[] attr // --------------------- private/protected helper methods ------------------- - static byte[] serializeSessionFields( final MemcachedBackupSession session ) { + byte[] serializeSessionFields( final MemcachedBackupSession session ) { return serializeSessionFields(session, VERSION_2); } - static byte[] serializeSessionFields( final MemcachedBackupSession session, final int version ) { + byte[] serializeSessionFields( final MemcachedBackupSession session, final int version ) { final byte[] idData = serializeId( session.getIdInternal() ); @@ -249,7 +260,7 @@ static byte[] serializeSessionFields( final MemcachedBackupSession session, fina return data; } - static DeserializationResult deserializeSessionFields( final byte[] data, final SessionManager manager ) throws InvalidVersionException { + DeserializationResult deserializeSessionFields( final byte[] data, final SessionManager manager ) throws InvalidVersionException { final MemcachedBackupSession result = manager.newMemcachedBackupSession(); final short version = (short) decodeNum( data, 0, 2 ); @@ -336,15 +347,15 @@ private static byte[] serializeId( final String id ) { } } - private static byte[] serializePrincipal( final Principal principal, final SessionManager manager ) { + private byte[] serializePrincipal( final Principal principal, final SessionManager manager ) { if(principal == null) { return null; } ByteArrayOutputStream bos = null; - ObjectOutputStream oos = null; + ObjectOutput oos = null; try { bos = new ByteArrayOutputStream(); - oos = new ObjectOutputStream( bos ); + oos = _objectIOStrategy.createObjectOutput(bos); manager.writePrincipal(principal, oos); oos.flush(); return bos.toByteArray(); @@ -356,12 +367,12 @@ private static byte[] serializePrincipal( final Principal principal, final Sessi } } - private static Principal deserializePrincipal( final byte[] data, final SessionManager manager ) { + private Principal deserializePrincipal( final byte[] data, final SessionManager manager ) { ByteArrayInputStream bis = null; - ObjectInputStream ois = null; + ObjectInput ois = null; try { bis = new ByteArrayInputStream( data ); - ois = new ObjectInputStream( bis ); + ois = _objectIOStrategy.createObjectInput(bis); return manager.readPrincipal( ois ); } catch ( final IOException e ) { throw new IllegalArgumentException( "Could not deserialize principal", e ); @@ -373,17 +384,17 @@ private static Principal deserializePrincipal( final byte[] data, final SessionM } } - private static byte[] serializeSavedRequest( final Object obj ) { + private byte[] serializeSavedRequest( final Object obj ) { if(obj == null) { return null; } final SavedRequest savedRequest = (SavedRequest) obj; ByteArrayOutputStream bos = null; - ObjectOutputStream oos = null; + ObjectOutput oos = null; try { bos = new ByteArrayOutputStream(); - oos = new ObjectOutputStream( bos ); + oos = _objectIOStrategy.createObjectOutput(bos); oos.writeObject(savedRequest.getBody()); oos.writeObject(savedRequest.getContentType()); // Cookies not cloneable... omit for now - oos.writeObject(newArrayList(savedRequest.getCookies())); @@ -406,12 +417,12 @@ private static byte[] serializeSavedRequest( final Object obj ) { } @SuppressWarnings("unchecked") - private static SavedRequest deserializeSavedRequest( final byte[] data ) { + private SavedRequest deserializeSavedRequest( final byte[] data ) { ByteArrayInputStream bis = null; - ObjectInputStream ois = null; + ObjectInput ois = null; try { bis = new ByteArrayInputStream( data ); - ois = new ObjectInputStream( bis ); + ois = _objectIOStrategy.createObjectInput(bis); final SavedRequest savedRequest = new SavedRequest(); savedRequest.setBody((ByteChunk) ois.readObject()); @@ -553,24 +564,24 @@ protected static int copy( final byte[] src, final byte[] dest, final int destBe return destBeginIndex + src.length; } - private static void closeSilently( final OutputStream os ) { - if ( os != null ) { + private static void closeSilently( final Closeable closeable ) { + if ( closeable != null ) { try { - os.close(); + closeable.close(); } catch ( final IOException f ) { // fail silently } } } - private static void closeSilently( final InputStream is ) { - if ( is != null ) { - try { - is.close(); - } catch ( final IOException f ) { - // fail silently - } - } + private static void closeSilently( final AutoCloseable closeable ) { + if ( closeable != null ) { + try { + closeable.close(); + } catch ( final Exception f ) { + // fail silently + } + } } /** diff --git a/core/src/test/java/de/javakaffee/web/msm/TranscoderServiceTest.java b/core/src/test/java/de/javakaffee/web/msm/TranscoderServiceTest.java index 3fd18363..5d4a1109 100644 --- a/core/src/test/java/de/javakaffee/web/msm/TranscoderServiceTest.java +++ b/core/src/test/java/de/javakaffee/web/msm/TranscoderServiceTest.java @@ -110,8 +110,8 @@ public void testSerializeSessionFieldsIncludesFormPrincipalNote() { final Principal saved = createPrincipal(); session.setNote(Constants.FORM_PRINCIPAL_NOTE, saved); - final byte[] data = TranscoderService.serializeSessionFields( session ); - final MemcachedBackupSession deserialized = TranscoderService.deserializeSessionFields(data, _manager ).getSession(); + final byte[] data = new TranscoderService(new JavaSerializationTranscoder()).serializeSessionFields( session ); + final MemcachedBackupSession deserialized = new TranscoderService(new JavaSerializationTranscoder()).deserializeSessionFields(data, _manager ).getSession(); final Principal actual = (Principal) deserialized.getNote(Constants.FORM_PRINCIPAL_NOTE); assertNotNull(actual); @@ -127,8 +127,8 @@ public void testSerializeSessionFieldsIncludesFormRequestNote() { saved.setRequestURI("http://www.foo.org"); session.setNote(Constants.FORM_REQUEST_NOTE, saved); - final byte[] data = TranscoderService.serializeSessionFields( session ); - final MemcachedBackupSession deserialized = TranscoderService.deserializeSessionFields(data, _manager ).getSession(); + final byte[] data = new TranscoderService(new JavaSerializationTranscoder()).serializeSessionFields( session ); + final MemcachedBackupSession deserialized = new TranscoderService(new JavaSerializationTranscoder()).deserializeSessionFields(data, _manager ).getSession(); final SavedRequest actual = (SavedRequest) deserialized.getNote(Constants.FORM_REQUEST_NOTE); assertNotNull(actual); @@ -139,8 +139,8 @@ public void testSerializeSessionFieldsIncludesFormRequestNote() { public void testVersionUpgrade() { final MemcachedBackupSession session = (MemcachedBackupSession) _manager.createSession( null ); - final byte[] data = TranscoderService.serializeSessionFields( session, TranscoderService.VERSION_1 ); - final byte[] attributesData = TranscoderService.deserializeSessionFields(data, _manager ).getAttributesData(); + final byte[] data = new TranscoderService(new JavaSerializationTranscoder()).serializeSessionFields( session, TranscoderService.VERSION_1 ); + final byte[] attributesData = new TranscoderService(new JavaSerializationTranscoder()).deserializeSessionFields(data, _manager ).getAttributesData(); // we just check that data is read (w/o) bounds issues and no data // is left (we just passed data in, w/o added attributesData appended) @@ -151,8 +151,8 @@ public void testVersionUpgrade() { public void testSerializeSessionFields() { final MemcachedBackupSession session = (MemcachedBackupSession) _manager.createSession( null ); session.setLastBackupTime( System.currentTimeMillis() ); - final byte[] data = TranscoderService.serializeSessionFields( session ); - final MemcachedBackupSession deserialized = TranscoderService.deserializeSessionFields(data, _manager ).getSession(); + final byte[] data = new TranscoderService(new JavaSerializationTranscoder()).serializeSessionFields( session ); + final MemcachedBackupSession deserialized = new TranscoderService(new JavaSerializationTranscoder()).deserializeSessionFields(data, _manager ).getSession(); assertSessionFields( session, deserialized ); } @@ -166,8 +166,8 @@ public void testSerializeSessionFieldsWithAuthenticatedPrincipal() { session.setLastBackupTime( System.currentTimeMillis() ); - final byte[] data = TranscoderService.serializeSessionFields( session ); - final MemcachedBackupSession deserialized = TranscoderService.deserializeSessionFields( data, _manager ).getSession(); + final byte[] data = new TranscoderService(new JavaSerializationTranscoder()).serializeSessionFields( session ); + final MemcachedBackupSession deserialized = new TranscoderService(new JavaSerializationTranscoder()).deserializeSessionFields( data, _manager ).getSession(); assertSessionFields( session, deserialized ); } diff --git a/kryo-serializer/pom.xml b/kryo-serializer/pom.xml index fec992b0..25742ec8 100644 --- a/kryo-serializer/pom.xml +++ b/kryo-serializer/pom.xml @@ -80,7 +80,7 @@ org.springframework.security spring-security-core - [4.2.9.RELEASE,5.0.0.M1) + 4.2.9.RELEASE true diff --git a/tomcat6/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java b/tomcat6/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java index b24cbdec..5971f344 100644 --- a/tomcat6/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java +++ b/tomcat6/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java @@ -22,8 +22,8 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.lang.reflect.Method; import java.security.Principal; import java.util.Map; @@ -1088,12 +1088,12 @@ public ClassLoader getContainerClassLoader() { } @Override - public void writePrincipal( @Nonnull Principal principal, @Nonnull ObjectOutputStream oos) throws IOException { + public void writePrincipal( @Nonnull Principal principal, @Nonnull ObjectOutput oos) throws IOException { SerializablePrincipal.writePrincipal((GenericPrincipal) principal, oos ); } @Override - public Principal readPrincipal( final ObjectInputStream ois ) throws ClassNotFoundException, IOException { + public Principal readPrincipal( final ObjectInput ois ) throws ClassNotFoundException, IOException { return SerializablePrincipal.readPrincipal( ois, getContainer().getRealm() ); } diff --git a/tomcat7/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java b/tomcat7/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java index e996efef..04788456 100644 --- a/tomcat7/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java +++ b/tomcat7/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java @@ -20,8 +20,8 @@ import static de.javakaffee.web.msm.Statistics.StatsType.*; import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.security.Principal; import java.util.Collection; import java.util.Map; @@ -909,12 +909,12 @@ public ClassLoader getContainerClassLoader() { } @Override - public void writePrincipal( @Nonnull Principal principal, @Nonnull ObjectOutputStream oos) throws IOException { + public void writePrincipal( @Nonnull Principal principal, @Nonnull ObjectOutput oos) throws IOException { SerializablePrincipal.writePrincipal((GenericPrincipal) principal, oos ); } @Override - public Principal readPrincipal( final ObjectInputStream ois ) throws ClassNotFoundException, IOException { + public Principal readPrincipal( final ObjectInput ois ) throws ClassNotFoundException, IOException { return SerializablePrincipal.readPrincipal( ois ); } diff --git a/tomcat8/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java b/tomcat8/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java index 9b3a82a6..136b6249 100644 --- a/tomcat8/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java +++ b/tomcat8/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java @@ -20,8 +20,8 @@ import static de.javakaffee.web.msm.Statistics.StatsType.*; import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.security.Principal; import java.util.Collection; import java.util.Map; @@ -886,12 +886,12 @@ public ClassLoader getContainerClassLoader() { } @Override - public void writePrincipal( @Nonnull Principal principal, @Nonnull ObjectOutputStream oos) throws IOException { + public void writePrincipal( @Nonnull Principal principal, @Nonnull ObjectOutput oos) throws IOException { oos.writeObject(principal); } @Override - public Principal readPrincipal( final ObjectInputStream ois ) throws ClassNotFoundException, IOException { + public Principal readPrincipal( final ObjectInput ois ) throws ClassNotFoundException, IOException { return (Principal) ois.readObject(); } diff --git a/tomcat9/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java b/tomcat9/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java index 9b3a82a6..136b6249 100644 --- a/tomcat9/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java +++ b/tomcat9/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java @@ -20,8 +20,8 @@ import static de.javakaffee.web.msm.Statistics.StatsType.*; import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.security.Principal; import java.util.Collection; import java.util.Map; @@ -886,12 +886,12 @@ public ClassLoader getContainerClassLoader() { } @Override - public void writePrincipal( @Nonnull Principal principal, @Nonnull ObjectOutputStream oos) throws IOException { + public void writePrincipal( @Nonnull Principal principal, @Nonnull ObjectOutput oos) throws IOException { oos.writeObject(principal); } @Override - public Principal readPrincipal( final ObjectInputStream ois ) throws ClassNotFoundException, IOException { + public Principal readPrincipal( final ObjectInput ois ) throws ClassNotFoundException, IOException { return (Principal) ois.readObject(); } From 3bb1d13f714c2d9592a792ec93492a0ad43d55be Mon Sep 17 00:00:00 2001 From: "Jonathan S. Fisher" Date: Mon, 7 Jun 2021 14:54:08 -0500 Subject: [PATCH 2/3] advance pom versions --- core/pom.xml | 4 ++-- flexjson-serializer/pom.xml | 4 ++-- kryo-serializer/pom.xml | 4 ++-- pom.xml | 2 +- tomcat6/pom.xml | 4 ++-- tomcat7/pom.xml | 4 ++-- tomcat8/pom.xml | 2 +- tomcat9/pom.xml | 2 +- xstream-serializer/pom.xml | 4 ++-- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 3cbee8fb..3a38afae 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,12 +3,12 @@ de.javakaffee.msm memcached-session-manager-project - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT de.javakaffee.msm memcached-session-manager - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT jar memcached-session-manager core The msm core, provides java serialization strategy. diff --git a/flexjson-serializer/pom.xml b/flexjson-serializer/pom.xml index a791a15e..e8c5987a 100644 --- a/flexjson-serializer/pom.xml +++ b/flexjson-serializer/pom.xml @@ -3,13 +3,13 @@ de.javakaffee.msm memcached-session-manager-project - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT de.javakaffee.msm msm-flexjson-serializer memcached-session-manager flexjson-serializer - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT jar diff --git a/kryo-serializer/pom.xml b/kryo-serializer/pom.xml index 25742ec8..95cf9930 100644 --- a/kryo-serializer/pom.xml +++ b/kryo-serializer/pom.xml @@ -3,12 +3,12 @@ de.javakaffee.msm memcached-session-manager-project - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT msm-kryo-serializer memcached-session-manager kryo-serializer - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT jar diff --git a/pom.xml b/pom.xml index c6e8e0c5..5a9d337b 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ de.javakaffee.msm memcached-session-manager-project - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT pom memcached-session-manager project diff --git a/tomcat6/pom.xml b/tomcat6/pom.xml index 6a63b571..f544eaae 100644 --- a/tomcat6/pom.xml +++ b/tomcat6/pom.xml @@ -3,12 +3,12 @@ de.javakaffee.msm memcached-session-manager-project - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT de.javakaffee.msm memcached-session-manager-tc6 - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT jar memcached-session-manager tomcat6 The msm tomcat6 specific implementation. diff --git a/tomcat7/pom.xml b/tomcat7/pom.xml index d9720f87..eb7e72a4 100644 --- a/tomcat7/pom.xml +++ b/tomcat7/pom.xml @@ -3,12 +3,12 @@ de.javakaffee.msm memcached-session-manager-project - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT de.javakaffee.msm memcached-session-manager-tc7 - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT jar memcached-session-manager tomcat7 The msm tomcat7 specific implementation. diff --git a/tomcat8/pom.xml b/tomcat8/pom.xml index ab57ed21..afa654b6 100644 --- a/tomcat8/pom.xml +++ b/tomcat8/pom.xml @@ -3,7 +3,7 @@ de.javakaffee.msm memcached-session-manager-project - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT memcached-session-manager-tc8 diff --git a/tomcat9/pom.xml b/tomcat9/pom.xml index 0e656b3d..502e990b 100644 --- a/tomcat9/pom.xml +++ b/tomcat9/pom.xml @@ -3,7 +3,7 @@ de.javakaffee.msm memcached-session-manager-project - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT memcached-session-manager-tc9 diff --git a/xstream-serializer/pom.xml b/xstream-serializer/pom.xml index 06afc7a1..3245583c 100644 --- a/xstream-serializer/pom.xml +++ b/xstream-serializer/pom.xml @@ -3,13 +3,13 @@ de.javakaffee.msm memcached-session-manager-project - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT de.javakaffee.msm msm-xstream-serializer memcached-session-manager xstream-serializer - 2.3.3-SNAPSHOT + 2.4.0-SNAPSHOT jar From a9f98d666d645e68719040827d9650ddc2ca8f01 Mon Sep 17 00:00:00 2001 From: "Jonathan S. Fisher" Date: Mon, 7 Jun 2021 16:43:05 -0500 Subject: [PATCH 3/3] add objectIOFactoryClassName to context manager --- .../web/msm/DefaultObjectIOFactory.java | 4 +- .../web/msm/DefaultObjectIOStrategy.java | 5 +- .../web/msm/MemcachedSessionService.java | 89 +++++++++++-------- .../javakaffee/web/msm/ObjectIOFactory.java | 4 +- .../javakaffee/web/msm/TranscoderService.java | 8 +- .../msm/MemcachedBackupSessionManager.java | 7 ++ .../msm/MemcachedBackupSessionManager.java | 7 ++ .../msm/MemcachedBackupSessionManager.java | 7 ++ .../msm/MemcachedBackupSessionManager.java | 7 ++ 9 files changed, 94 insertions(+), 44 deletions(-) diff --git a/core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOFactory.java b/core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOFactory.java index 70dce4cb..cf138344 100644 --- a/core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOFactory.java +++ b/core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOFactory.java @@ -1,8 +1,10 @@ package de.javakaffee.web.msm; +import de.javakaffee.web.msm.MemcachedSessionService.SessionManager; + public class DefaultObjectIOFactory implements ObjectIOFactory { @Override - public ObjectIOStrategy createObjectIOStrategy() { + public ObjectIOStrategy createObjectIOStrategy(final SessionManager _manager) { return new DefaultObjectIOStrategy(); } } diff --git a/core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOStrategy.java b/core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOStrategy.java index 6c52f695..12e5ded8 100644 --- a/core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOStrategy.java +++ b/core/src/main/java/de/javakaffee/web/msm/DefaultObjectIOStrategy.java @@ -9,14 +9,13 @@ import java.io.OutputStream; public class DefaultObjectIOStrategy implements ObjectIOStrategy { - @Override - public ObjectInput createObjectInput(InputStream is) throws IOException { + public ObjectInput createObjectInput(final InputStream is) throws IOException { return new ObjectInputStream(is); } @Override - public ObjectOutput createObjectOutput(OutputStream os) throws IOException { + public ObjectOutput createObjectOutput(final OutputStream os) throws IOException { return new ObjectOutputStream(os); } } diff --git a/core/src/main/java/de/javakaffee/web/msm/MemcachedSessionService.java b/core/src/main/java/de/javakaffee/web/msm/MemcachedSessionService.java index da8fbda4..ccb3953c 100644 --- a/core/src/main/java/de/javakaffee/web/msm/MemcachedSessionService.java +++ b/core/src/main/java/de/javakaffee/web/msm/MemcachedSessionService.java @@ -162,15 +162,23 @@ static enum LockStatus { * {@link JavaSerializationTranscoderFactory}. */ private String _transcoderFactoryClassName = JavaSerializationTranscoderFactory.class.getName(); - + /** * The class name of the factory for - * {@link net.spy.memcached.transcoders.Transcoder}s. Default class name is - * {@link JavaSerializationTranscoderFactory}. + * {@link de.javakaffee.web.msm.ObjectIOFactory}s. Default class name is + * {@link de.javakaffee.web.msm.DefaultObjectIOFactory}. */ private String _objectIOFactoryClassName = DefaultObjectIOFactory.class.getName(); - /** + public String getObjectIOFactoryClassName() { + return _objectIOFactoryClassName; + } + + public void setObjectIOFactoryClassName(final String objectIOFactoryClassName) { + this._objectIOFactoryClassName = objectIOFactoryClassName; + } + + /** * Specifies, if iterating over collection elements shall be done on a copy * of the collection or on the collection itself. *

@@ -305,8 +313,10 @@ public static interface SessionManager extends Manager { String getString(final String key, final Object... args); boolean isMaxInactiveIntervalSet(); - int getMaxInactiveInterval(); - void setMaxInactiveInterval(int interval); + @Override + int getMaxInactiveInterval(); + @Override + void setMaxInactiveInterval(int interval); int getMaxActiveSessions(); void incrementSessionCounter(); @@ -427,11 +437,12 @@ public void shutdown() { * @param storage the storage client to use, for normal operations this should be null. */ void startInternal( final StorageClient storage ) throws LifecycleException { - if (storage == null) - _storage = null; - else - _storage = storage; - + if (storage == null) { + _storage = null; + } else { + _storage = storage; + } + startInternal(); } @@ -506,7 +517,7 @@ protected MemcachedNodesManager createMemcachedNodesManager(final String memcach } private TranscoderService createTranscoderService( final Statistics statistics ) { - return new TranscoderService( getTranscoderFactory().createTranscoder( _manager ), getObjectIOFactory().createObjectIOStrategy() ); + return new TranscoderService( getTranscoderFactory().createTranscoder( _manager ), getObjectIOFactory().createObjectIOStrategy( _manager ) ); } protected TranscoderFactory getTranscoderFactory() { @@ -519,7 +530,7 @@ protected TranscoderFactory getTranscoderFactory() { } return _transcoderFactory; } - + protected ObjectIOFactory getObjectIOFactory() { if ( _objectIOFactory == null ) { try { @@ -553,7 +564,7 @@ private TranscoderFactory createTranscoderFactory() throws InstantiationExceptio } return transcoderFactory; } - + private ObjectIOFactory createObjectIOFactory() throws InstantiationException, IllegalAccessException, ClassNotFoundException { _log.info( "Creating objectIO factory " + _objectIOFactoryClassName ); final Class objectIOFactoryClass = loadFactoryClass(_objectIOFactoryClassName, _manager.getContainerClassLoader(), ObjectIOFactory.class); @@ -562,7 +573,7 @@ private ObjectIOFactory createObjectIOFactory() throws InstantiationException, I } - private Class loadFactoryClass(String className, ClassLoader classLoader, Class factoryInterface) throws ClassNotFoundException { + private Class loadFactoryClass(final String className, final ClassLoader classLoader, final Class factoryInterface) throws ClassNotFoundException { Class factoryClass; try { _log.debug( "Loading transcoder factory class " + className + " using classloader " + classLoader ); @@ -751,7 +762,7 @@ public MemcachedBackupSession createSession( String sessionId ) { if ( _log.isDebugEnabled() ) { _log.debug( "Remove session id " + session.getId() + " from _invalidSessionsCache, marking new session valid" ); } - _invalidSessionsCache.remove(session.getId()); + _invalidSessionsCache.remove(session.getId()); } return session; @@ -998,15 +1009,17 @@ private MemcachedBackupSession loadBackupSession(final String requestedSessionId try { final SessionValidityInfo validityInfo = _lockingStrategy.loadBackupSessionValidityInfo( requestedSessionId ); if ( validityInfo == null || !validityInfo.isValid() ) { - if(_log.isDebugEnabled()) - _log.debug( "No validity info (or no valid one) found for sessionId " + requestedSessionId ); + if(_log.isDebugEnabled()) { + _log.debug( "No validity info (or no valid one) found for sessionId " + requestedSessionId ); + } return null; } final byte[] obj = _storage.get( getSessionIdFormat().createBackupKey( requestedSessionId ) ); if ( obj == null ) { - if(_log.isDebugEnabled()) - _log.debug( "No backup found for sessionId " + requestedSessionId ); + if(_log.isDebugEnabled()) { + _log.debug( "No backup found for sessionId " + requestedSessionId ); + } return null; } @@ -1036,14 +1049,16 @@ public void requestFinished(final String sessionId, final String requestId) { if(!_sticky) { final MemcachedBackupSession msmSession = _manager.getSessionInternal( sessionId ); if ( msmSession == null ) { - if(_log.isDebugEnabled()) - _log.debug( "No session found in session map for " + sessionId ); + if(_log.isDebugEnabled()) { + _log.debug( "No session found in session map for " + sessionId ); + } return; } if ( !msmSession.isValidInternal() ) { - if(_log.isDebugEnabled()) - _log.debug( "Non valid session found in session map for " + sessionId ); + if(_log.isDebugEnabled()) { + _log.debug( "Non valid session found in session map for " + sessionId ); + } return; } @@ -1052,8 +1067,9 @@ public void requestFinished(final String sessionId, final String requestId) { // we must not remove it as this would case session data loss // for the other request if ( msmSession.releaseReference() > 0 ) { - if(_log.isDebugEnabled()) - _log.debug( "Session " + sessionId + " is still used by another request, skipping backup and (optional) lock handling/release." ); + if(_log.isDebugEnabled()) { + _log.debug( "Session " + sessionId + " is still used by another request, skipping backup and (optional) lock handling/release." ); + } return; } msmSession.passivate(); @@ -1090,8 +1106,9 @@ public Future backupSession( final String sessionId, final boolean final MemcachedBackupSession msmSession = _manager.getSessionInternal( sessionId ); if ( msmSession == null ) { - if(_log.isDebugEnabled()) - _log.debug( "No session found in session map for " + sessionId ); + if(_log.isDebugEnabled()) { + _log.debug( "No session found in session map for " + sessionId ); + } if ( !_sticky ) { // Issue 116/137: Only notify the lockingStrategy if the session was loaded and has not been removed/invalidated if(!_invalidSessionsCache.containsKey(sessionId)) { @@ -1102,8 +1119,9 @@ public Future backupSession( final String sessionId, final boolean } if ( !msmSession.isValidInternal() ) { - if(_log.isDebugEnabled()) - _log.debug( "Non valid session found in session map for " + sessionId ); + if(_log.isDebugEnabled()) { + _log.debug( "Non valid session found in session map for " + sessionId ); + } return new SimpleFuture( BackupResult.SKIPPED ); } @@ -1113,8 +1131,9 @@ public Future backupSession( final String sessionId, final boolean // we must not remove it as this would case session data loss // for the other request if ( msmSession.releaseReference() > 0 ) { - if(_log.isDebugEnabled()) - _log.debug( "Session " + sessionId + " is still used by another request, skipping backup and (optional) lock handling/release." ); + if(_log.isDebugEnabled()) { + _log.debug( "Session " + sessionId + " is still used by another request, skipping backup and (optional) lock handling/release." ); + } return new SimpleFuture( BackupResult.SKIPPED ); } msmSession.passivate(); @@ -1122,7 +1141,7 @@ public Future backupSession( final String sessionId, final boolean } } - final boolean force = sessionIdChanged || msmSession.isSessionIdChanged() || !_sticky && (msmSession.getSecondsSinceLastBackup() >= msmSession.getMaxInactiveInterval()); + final boolean force = sessionIdChanged || msmSession.isSessionIdChanged() || !_sticky && msmSession.getSecondsSinceLastBackup() >= msmSession.getMaxInactiveInterval(); final Future result = _backupSessionService.backupSession( msmSession, force ); if ( !_sticky ) { @@ -1256,7 +1275,7 @@ public void setMemcachedNodes( final String memcachedNodes ) { public String getMemcachedNodes() { return _memcachedNodes; } - + private MemcachedNodesManager reloadMemcachedConfig( final String memcachedNodes, final String failoverNodes ) { /* first create all dependent services @@ -1666,7 +1685,7 @@ protected void updateExpirationInMemcached() { public void setSessionBackupAsync( final boolean sessionBackupAsync ) { final boolean oldSessionBackupAsync = _sessionBackupAsync; _sessionBackupAsync = sessionBackupAsync; - if ( ( oldSessionBackupAsync != sessionBackupAsync ) && _manager.isInitialized() ) { + if ( oldSessionBackupAsync != sessionBackupAsync && _manager.isInitialized() ) { _log.info( "SessionBackupAsync was changed to " + sessionBackupAsync + ", creating new BackupSessionService with new configuration." ); _backupSessionService = new BackupSessionService( _transcoderService, _sessionBackupAsync, _sessionBackupTimeout, _backupThreadCount, _storage, _memcachedNodesManager, _statistics ); diff --git a/core/src/main/java/de/javakaffee/web/msm/ObjectIOFactory.java b/core/src/main/java/de/javakaffee/web/msm/ObjectIOFactory.java index 152146b5..660a71e2 100644 --- a/core/src/main/java/de/javakaffee/web/msm/ObjectIOFactory.java +++ b/core/src/main/java/de/javakaffee/web/msm/ObjectIOFactory.java @@ -1,5 +1,7 @@ package de.javakaffee.web.msm; +import de.javakaffee.web.msm.MemcachedSessionService.SessionManager; + public interface ObjectIOFactory { - ObjectIOStrategy createObjectIOStrategy(); + ObjectIOStrategy createObjectIOStrategy(SessionManager sessionManager); } diff --git a/core/src/main/java/de/javakaffee/web/msm/TranscoderService.java b/core/src/main/java/de/javakaffee/web/msm/TranscoderService.java index db067dfe..b3695a34 100644 --- a/core/src/main/java/de/javakaffee/web/msm/TranscoderService.java +++ b/core/src/main/java/de/javakaffee/web/msm/TranscoderService.java @@ -79,13 +79,13 @@ public TranscoderService( final SessionAttributesTranscoder attributesTranscoder _attributesTranscoder = attributesTranscoder; _objectIOStrategy = new DefaultObjectIOStrategy(); } - + /** * Creates a new {@link TranscoderService}. * * @param attributesTranscoder the {@link SessionAttributesTranscoder} strategy to use. */ - public TranscoderService( final SessionAttributesTranscoder attributesTranscoder, ObjectIOStrategy objectIOStrategy) { + public TranscoderService( final SessionAttributesTranscoder attributesTranscoder, final ObjectIOStrategy objectIOStrategy) { _attributesTranscoder = attributesTranscoder; _objectIOStrategy = objectIOStrategy; } @@ -512,7 +512,7 @@ public static int encodeNum( final long num, final byte[] data, final int beginI for ( int i = 0; i < maxBytes; i++ ) { final int pos = maxBytes - i - 1; // the position of the byte in the number final int idx = beginIndex + pos; // the index in the data array - data[idx] = (byte) ( ( num >> ( 8 * i ) ) & 0xff ); + data[idx] = (byte) ( num >> 8 * i & 0xff ); } return beginIndex + maxBytes; } @@ -521,7 +521,7 @@ public static long decodeNum( final byte[] data, final int beginIndex, final int long result = 0; for ( int i = 0; i < numBytes; i++ ) { final byte b = data[beginIndex + i]; - result = ( result << 8 ) | ( b < 0 + result = result << 8 | ( b < 0 ? 256 + b : b ); } diff --git a/tomcat6/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java b/tomcat6/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java index 5971f344..33e53518 100644 --- a/tomcat6/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java +++ b/tomcat6/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java @@ -1120,4 +1120,11 @@ public String[] getSetCookieHeaders(final Response response) { return response.getHeaderValues("Set-Cookie"); } + public String getObjectIOFactoryClassName() { + return _msm.getObjectIOFactoryClassName(); + } + + public void setObjectIOFactoryClassName(final String objectIOFactoryClassName) { + _msm.setObjectIOFactoryClassName(objectIOFactoryClassName); + } } diff --git a/tomcat7/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java b/tomcat7/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java index 04788456..8e9815d8 100644 --- a/tomcat7/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java +++ b/tomcat7/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java @@ -942,4 +942,11 @@ public String[] getSetCookieHeaders(final Response response) { return result.toArray(new String[result.size()]); } + public String getObjectIOFactoryClassName() { + return _msm.getObjectIOFactoryClassName(); + } + + public void setObjectIOFactoryClassName(final String objectIOFactoryClassName) { + _msm.setObjectIOFactoryClassName(objectIOFactoryClassName); + } } diff --git a/tomcat8/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java b/tomcat8/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java index 136b6249..41c00a43 100644 --- a/tomcat8/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java +++ b/tomcat8/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java @@ -917,4 +917,11 @@ public String[] getSetCookieHeaders(final Response response) { return result.toArray(new String[result.size()]); } + public String getObjectIOFactoryClassName() { + return _msm.getObjectIOFactoryClassName(); + } + + public void setObjectIOFactoryClassName(final String objectIOFactoryClassName) { + _msm.setObjectIOFactoryClassName(objectIOFactoryClassName); + } } diff --git a/tomcat9/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java b/tomcat9/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java index 136b6249..41c00a43 100644 --- a/tomcat9/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java +++ b/tomcat9/src/main/java/de/javakaffee/web/msm/MemcachedBackupSessionManager.java @@ -917,4 +917,11 @@ public String[] getSetCookieHeaders(final Response response) { return result.toArray(new String[result.size()]); } + public String getObjectIOFactoryClassName() { + return _msm.getObjectIOFactoryClassName(); + } + + public void setObjectIOFactoryClassName(final String objectIOFactoryClassName) { + _msm.setObjectIOFactoryClassName(objectIOFactoryClassName); + } }