Skip to content

Commit

Permalink
Create Default Serializer via a Factory method
Browse files Browse the repository at this point in the history
Thus it is configurable from outside which Serializer and with
which configuration is actually used as default.
  • Loading branch information
Marcus Thiesen committed Jan 17, 2014
1 parent b2715e8 commit f1f9f0a
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2014 Marcus Thiesen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package de.javakaffee.web.msm.serializer.kryo;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.serialize.CompatibleFieldSerializer;

/**
* Default Serializer Factory that creates a {@link CompatibleFieldSerializer}
*
* @author Marcus Thiesen ([email protected]) (initial creation)
*/
public class CompatibleFieldSerializerFactory implements KryoDefaultSerializerFactory {

@Override
public Serializer newDefaultSerializer( Kryo kryo, Class<?> type ) {
return new CompatibleFieldSerializer( kryo, type );
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2014 Marcus Thiesen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package de.javakaffee.web.msm.serializer.kryo;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;

/**
* Interface for creating default Serializers for Kryo.
*
* @author Marcus Thiesen ([email protected]) (initial creation)
*/
public interface KryoDefaultSerializerFactory {

/**
* Should return the Serializer used by Kryo when
* {@link Kryo#newDefaultSerializer} is called.
*/
public Serializer newDefaultSerializer( Kryo kryo, Class<?> type );


}
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,15 @@ public class KryoTranscoder implements SessionAttributesTranscoder {

public static final int DEFAULT_INITIAL_BUFFER_SIZE = 100 * 1024;
public static final int DEFAULT_MAX_BUFFER_SIZE = 2000 * 1024;
public static final String DEFAULT_SERIALIZER_FACTORY_CLASS = "de.javakaffee.web.msm.serializer.kryo.ReferenceFieldSerializerFactory";

private final Kryo _kryo;
private final SerializerFactory[] _serializerFactories;
private final UnregisteredClassHandler[] _unregisteredClassHandlers;

private final int _initialBufferSize;
private final int _maxBufferSize;
private final KryoDefaultSerializerFactory _defaultSerializerFactory;

/**
*
Expand All @@ -105,7 +107,8 @@ public KryoTranscoder() {
* @param customConverterClassNames
*/
public KryoTranscoder( final ClassLoader classLoader, final String[] customConverterClassNames, final boolean copyCollectionsForSerialization ) {
this( classLoader, customConverterClassNames, copyCollectionsForSerialization, DEFAULT_INITIAL_BUFFER_SIZE, DEFAULT_MAX_BUFFER_SIZE );
this( classLoader, customConverterClassNames, copyCollectionsForSerialization, DEFAULT_INITIAL_BUFFER_SIZE, DEFAULT_MAX_BUFFER_SIZE,
DEFAULT_SERIALIZER_FACTORY_CLASS );
}

/**
Expand All @@ -114,14 +117,27 @@ public KryoTranscoder( final ClassLoader classLoader, final String[] customConve
* @param customConverterClassNames
*/
public KryoTranscoder( final ClassLoader classLoader, final String[] customConverterClassNames,
final boolean copyCollectionsForSerialization, final int initialBufferSize, final int maxBufferSize ) {
final boolean copyCollectionsForSerialization, final int initialBufferSize, final int maxBufferSize,
final String defaultSerializerFactoryClass ) {
LOG.info( "Starting with initialBufferSize " + initialBufferSize + " and maxBufferSize " + maxBufferSize );
final Triple<Kryo, SerializerFactory[], UnregisteredClassHandler[]> triple = createKryo( classLoader, customConverterClassNames, copyCollectionsForSerialization );
_kryo = triple.a;
_serializerFactories = triple.b;
_unregisteredClassHandlers = triple.c;
_initialBufferSize = initialBufferSize;
_maxBufferSize = maxBufferSize;
_defaultSerializerFactory = loadDefaultSerializerFactory( classLoader, defaultSerializerFactoryClass );
}

protected KryoDefaultSerializerFactory loadDefaultSerializerFactory( final ClassLoader classLoader, final String defaultSerializerFactoryClass ) {
try {
final ClassLoader loader = classLoader != null ? classLoader : Thread.currentThread().getContextClassLoader();
final Class<?> clazz = Class.forName( defaultSerializerFactoryClass, true, loader );

return (KryoDefaultSerializerFactory) clazz.newInstance();
} catch ( Exception e ) {
throw new RuntimeException("Could not load default serializer factory: " + defaultSerializerFactoryClass, e );
}
}

private Triple<Kryo, SerializerFactory[], UnregisteredClassHandler[]> createKryo( final ClassLoader classLoader,
Expand Down Expand Up @@ -174,6 +190,11 @@ protected void handleUnregisteredClass( final Class clazz ) {
super.handleUnregisteredClass( clazz );
}

@Override
protected Serializer newDefaultSerializer( @SuppressWarnings( "rawtypes" ) Class type ) {
return _defaultSerializerFactory.newDefaultSerializer( this, type );
}

};

if ( classLoader != null ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class KryoTranscoderFactory implements TranscoderFactory {

public static final String PROP_INIT_BUFFER_SIZE = "msm.kryo.buffersize.initial";
public static final String PROP_ENV_MAX_BUFFER_SIZE = "msm.kryo.buffersize.max";
public static final String PROP_ENV_DEFAULT_FACTORY = "msm.kryo.default.serializer.factory";

private boolean _copyCollectionsForSerialization;
private String[] _customConverterClassNames;
Expand All @@ -58,8 +59,10 @@ private KryoTranscoder getTranscoder( final Manager manager ) {
if ( _transcoder == null ) {
final int initialBufferSize = getSysPropValue( PROP_INIT_BUFFER_SIZE, KryoTranscoder.DEFAULT_INITIAL_BUFFER_SIZE );
final int maxBufferSize = getSysPropValue( PROP_ENV_MAX_BUFFER_SIZE, KryoTranscoder.DEFAULT_MAX_BUFFER_SIZE );
final String defaultSerializerFactory = getSysPropValue( PROP_ENV_DEFAULT_FACTORY, KryoTranscoder.DEFAULT_SERIALIZER_FACTORY_CLASS );
_transcoder = new KryoTranscoder( manager.getContainer().getLoader().getClassLoader(),
_customConverterClassNames, _copyCollectionsForSerialization, initialBufferSize, maxBufferSize );
_customConverterClassNames, _copyCollectionsForSerialization, initialBufferSize, maxBufferSize,
defaultSerializerFactory );
}
return _transcoder;
}
Expand All @@ -77,6 +80,14 @@ private int getSysPropValue( final String propName, final int defaultValue ) {
return value;
}

private String getSysPropValue( final String propName, final String defaultValue ) {
final String propValue = System.getProperty( propName );
if ( propValue == null || propValue.trim().length() == 0 ) {
return defaultValue;
}
return propValue;
}

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2014 Marcus Thiesen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package de.javakaffee.web.msm.serializer.kryo;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.serialize.ReferenceFieldSerializer;

/**
* Default Serializer used by memcached-session-manager.
* Creates a {@link ReferenceFieldSerializer} which does not ignores synthetic fields.
*
* @author Marcus Thiesen ([email protected]) (initial creation)
*/
public class ReferenceFieldSerializerFactory implements KryoDefaultSerializerFactory {

@Override
public Serializer newDefaultSerializer( final Kryo kryo, final Class<?> type ) {
final ReferenceFieldSerializer result = new ReferenceFieldSerializer( kryo, type );
result.setIgnoreSyntheticFields( false );
return result;
}

}

0 comments on commit f1f9f0a

Please sign in to comment.