magro / kryo-serializers

More kryo serializers
Apache License 2.0
381 stars 120 forks source link

A project that provides kryo (v2, v3, v4) serializers for some jdk types and some external libs like e.g. joda time.

Build Status Coverage Status Maven Central

Provided serializers / supporting classes:

Usage

To be able to use the serializers you have to add the jar to your classpath. If your build tool support maven repositories you can use this dependency:

<dependency>
    <groupId>de.javakaffee</groupId>
    <artifactId>kryo-serializers</artifactId>
    <version>0.45</version>
</dependency>

It's available in maven central, so you don't need an additional repository definition. If you're managing the classpath differently you can get the jar from the downloads section or download from maven central.

After that's done you can register the custom serializers at the kryo instance. The following code snippet shows how this is done for serializers that can be registered statically (directly for a known class).

kryo.register( Arrays.asList( "" ).getClass(), new ArraysAsListSerializer() );
kryo.register( Collections.EMPTY_LIST.getClass(), new CollectionsEmptyListSerializer() );
kryo.register( Collections.EMPTY_MAP.getClass(), new CollectionsEmptyMapSerializer() );
kryo.register( Collections.EMPTY_SET.getClass(), new CollectionsEmptySetSerializer() );
kryo.register( Collections.singletonList( "" ).getClass(), new CollectionsSingletonListSerializer() );
kryo.register( Collections.singleton( "" ).getClass(), new CollectionsSingletonSetSerializer() );
kryo.register( Collections.singletonMap( "", "" ).getClass(), new CollectionsSingletonMapSerializer() );
kryo.register( GregorianCalendar.class, new GregorianCalendarSerializer() );
kryo.register( InvocationHandler.class, new JdkProxySerializer() );
UnmodifiableCollectionsSerializer.registerSerializers( kryo );
SynchronizedCollectionsSerializer.registerSerializers( kryo );

// custom serializers for non-jdk libs

// register CGLibProxySerializer, works in combination with the appropriate action in handleUnregisteredClass (see below)
kryo.register( CGLibProxySerializer.CGLibProxyMarker.class, new CGLibProxySerializer( kryo ) );
// dexx
ListSerializer.registerSerializers( kryo );
MapSerializer.registerSerializers( kryo );
SetSerializer.registerSerializers( kryo );
// joda DateTime, LocalDate, LocalDateTime and LocalTime
kryo.register( DateTime.class, new JodaDateTimeSerializer() );
kryo.register( LocalDate.class, new JodaLocalDateSerializer() );
kryo.register( LocalDateTime.class, new JodaLocalDateTimeSerializer() );
kryo.register( LocalDateTime.class, new JodaLocalTimeSerializer() );
// protobuf
kryo.register( SampleProtoA.class, new ProtobufSerializer() ); // or override Kryo.getDefaultSerializer as shown below
// wicket
kryo.register( MiniMap.class, new MiniMapSerializer() );
// guava ImmutableList, ImmutableSet, ImmutableMap, ImmutableMultimap, ImmutableTable, ReverseList, UnmodifiableNavigableSet
ImmutableListSerializer.registerSerializers( kryo );
ImmutableSetSerializer.registerSerializers( kryo );
ImmutableMapSerializer.registerSerializers( kryo );
ImmutableMultimapSerializer.registerSerializers( kryo );
ImmutableTableSerializer.registerSerializers( kryo );
ReverseListSerializer.registerSerializers( kryo );
UnmodifiableNavigableSetSerializer.registerSerializers( kryo );
// guava ArrayListMultimap, HashMultimap, LinkedHashMultimap, LinkedListMultimap, TreeMultimap, ArrayTable, HashBasedTable, TreeBasedTable
ArrayListMultimapSerializer.registerSerializers( kryo );
HashMultimapSerializer.registerSerializers( kryo );
LinkedHashMultimapSerializer.registerSerializers( kryo );
LinkedListMultimapSerializer.registerSerializers( kryo );
TreeMultimapSerializer.registerSerializers( kryo );
ArrayTableSerializer.registerSerializers( kryo );
HashBasedTableSerializer.registerSerializers( kryo );
TreeBasedTableSerializer.registerSerializers( kryo );

The following code snippet shows how to use the KryoReflectionFactorySupport (can only be used with sun/oracle jdk!) and how other serializers are registered via the getDefaultSerializer lookup. If you don't want to use the KryoReflectionFactorySupport you can override the getDefaultSerializer method for your new Kryo() instance.

final Kryo kryo = new KryoReflectionFactorySupport() {

    @Override
    public Serializer<?> getDefaultSerializer(final Class clazz) {
        if ( EnumSet.class.isAssignableFrom( clazz ) ) {
            return new EnumSetSerializer();
        }
        if ( EnumMap.class.isAssignableFrom( clazz ) ) {
            return new EnumMapSerializer();
        }
        if ( SubListSerializers.canSerialize( clazz ) ) {
            return SubListSerializers.createFor( clazz );
        }
        if ( copyCollectionsForSerialization ) {
            if ( Collection.class.isAssignableFrom( clazz ) ) {
                return new CopyForIterateCollectionSerializer();
            }
            if ( Map.class.isAssignableFrom( clazz ) ) {
                return new CopyForIterateMapSerializer();
            }
        }
        if ( Date.class.isAssignableFrom( type ) ) {
            return new DateSerializer( type );
        }
        // see if the given class is a cglib proxy
        if ( CGLibProxySerializer.canSerialize( type ) ) {
            // return the serializer registered for CGLibProxyMarker.class (see above)
            return getSerializer( CGLibProxySerializer.CGLibProxyMarker.class );
        }
        // protobuf
        if ( com.google.protobuf.GeneratedMessage.class.isAssignableFrom( type ) ) {
            return new ProtobufSerializer();
        }
        return super.getDefaultSerializer( clazz );
    }

};

Where to get help

You can contact me via github or submit an issue.

How to contribute

If you want to contribute to this project you can fork the sources on github, make your changes and submit a pull request. Alternatively you can submit an issue with a patch attached.