Permalink
Browse files

init commit

  • Loading branch information...
michaelmosmann committed Oct 11, 2012
1 parent 7cdad58 commit 41cb98a518339e8ec2929872413fb19d5acc4438
View
@@ -23,6 +23,7 @@
<module>javaee-inject-parent</module>
<module>push-parent-jdk-1.6</module>
<module>serializer-kryo</module>
+ <module>serializer-kryo2</module>
<module>wicket-html5-parent</module>
<module>wicket-servlet3-parent</module>
<module>wicket-facebook-parent</module>
@@ -0,0 +1,30 @@
+Serializer Kryo
+===============
+is an implementation of `org.apache.wicket.serialize.ISerializer` for Wicket 1.5
+
+Such serializer can be used to convert almost any kind of object to/from byte array. Almost any because Kryo may need your help for some complex graph of objects. Refer to Kryo documentation to understand more about that.
+
+When configured with
+
+
+ public class MyApplication extends WebApplication
+ {
+ @Override
+ public void init()
+ {
+ super.init();
+
+ getFrameworkSettings().setSerializer(new KryoSerializer());
+ }
+ }
+
+
+it will be used to serialize any page for the IPageStore needs.
+
+It is based on [Kryo](http://code.google.com/p/kryo/) and [kryo-serializers](https://github.com/magro/kryo-serializers).
+
+Notes
+----
+* serializer-kryo is not heavily tested so it may have need for more custom serializers for some of the Wicket classes. Let us know if you face a problem by creating an issue. Pull requests are more than welcome!
+
+* serializer-kryo uses SUN/Oracle propriate APIs (sun.reflect.ReflectionFactory) and thus cannot be used on different JDKs.
@@ -0,0 +1,43 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.wicketstuff</groupId>
+ <artifactId>jdk-1.6-parent</artifactId>
+ <version>1.5-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>wicketstuff-serializer-kryo2</artifactId>
+
+ <name>WicketStuff Kryo2 serializer</name>
+ <description>ISerializer based on http://code.google.com/p/kryo/ (v2)</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <!--
+ <dependency>
+ <groupId>com.esotericsoftware.kryo</groupId>
+ <artifactId>kryo</artifactId>
+ <version>2.20</version>
+ </dependency>
+ -->
+ <dependency>
+ <groupId>de.javakaffee</groupId>
+ <artifactId>kryo-serializers</artifactId>
+ <version>0.20</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty.aggregate</groupId>
+ <artifactId>jetty-all-server</artifactId>
+ </dependency>
+ </dependencies>
+</project>
@@ -0,0 +1,65 @@
+package org.wicketstuff.pageserializer.kryo;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.wicket.util.lang.Args;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import de.javakaffee.kryoserializers.KryoReflectionFactorySupport;
+
+/**
+ * An extension of {@link KryoReflectionFactorySupport} that logs the serialized objects and the
+ * current size of the buffer after the write. Additionally provides the functionality to blacklist
+ * the serialization of specific classes.
+ */
+public class DebuggingKryo extends KryoReflectionFactorySupport
+{
+
+ private final static Logger LOG = LoggerFactory.getLogger(DebuggingKryo.class);
+
+ private final List<Class<?>> blackList;
+
+ public DebuggingKryo()
+ {
+ blackList = new ArrayList<Class<?>>();
+ }
+
+ public DebuggingKryo blacklist(final Class<?>... classes)
+ {
+ Args.notNull(classes, "classes");
+
+ for (Class<?> cls : classes)
+ {
+ blackList.add(cls);
+ }
+ return this;
+ }
+
+ @Override
+ public void writeClassAndObject(ByteBuffer buffer, Object object)
+ {
+
+ if (object != null)
+ {
+ Class<? extends Object> target = object.getClass();
+ for (Class<?> cls : blackList)
+ {
+ if (cls.isAssignableFrom(target))
+ {
+ throw new IllegalArgumentException("Should not serialize class with type: " +
+ cls.getName());
+ }
+ }
+ }
+ super.writeClassAndObject(buffer, object);
+
+ if (object != null)
+ {
+ LOG.error("Wrote '{}' bytes for object: '{}'", buffer.position(), object.getClass());
+ }
+ }
+
+}
@@ -0,0 +1,190 @@
+package org.wicketstuff.pageserializer.kryo;
+
+import java.lang.reflect.InvocationHandler;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Currency;
+import java.util.GregorianCalendar;
+
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.serialize.ISerializer;
+import org.apache.wicket.util.lang.Args;
+import org.apache.wicket.util.lang.Bytes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.Serializer;
+
+import de.javakaffee.kryoserializers.ArraysAsListSerializer;
+import de.javakaffee.kryoserializers.ClassSerializer;
+import de.javakaffee.kryoserializers.CollectionsEmptyListSerializer;
+import de.javakaffee.kryoserializers.CollectionsEmptyMapSerializer;
+import de.javakaffee.kryoserializers.CollectionsEmptySetSerializer;
+import de.javakaffee.kryoserializers.CollectionsSingletonListSerializer;
+import de.javakaffee.kryoserializers.CollectionsSingletonMapSerializer;
+import de.javakaffee.kryoserializers.CollectionsSingletonSetSerializer;
+import de.javakaffee.kryoserializers.CurrencySerializer;
+import de.javakaffee.kryoserializers.GregorianCalendarSerializer;
+import de.javakaffee.kryoserializers.JdkProxySerializer;
+import de.javakaffee.kryoserializers.KryoReflectionFactorySupport;
+import de.javakaffee.kryoserializers.StringBufferSerializer;
+import de.javakaffee.kryoserializers.StringBuilderSerializer;
+import de.javakaffee.kryoserializers.SynchronizedCollectionsSerializer;
+import de.javakaffee.kryoserializers.UnmodifiableCollectionsSerializer;
+import de.javakaffee.kryoserializers.cglib.CGLibProxySerializer;
+
+/**
+ * An {@link ISerializer} based on <a href="http://code.google.com/p/kryo">kryo</a> and <a
+ * href="https://github.com/magro/kryo-serializers">additional kryo serializers</a>
+ */
+public class KryoSerializer implements ISerializer
+{
+
+ private static final Logger LOG = LoggerFactory.getLogger(KryoSerializer.class);
+
+ /**
+ * The size of the {@link ByteBuffer} that is used to hold the serialized page
+ */
+ private static final Bytes DEFAULT_BUFFER_SIZE = Bytes.megabytes(10L);
+
+ private final Bytes bufferSize;
+
+ private final Kryo kryo;
+
+ public KryoSerializer()
+ {
+ this(DEFAULT_BUFFER_SIZE);
+ }
+
+ public KryoSerializer(final Bytes bufferSize)
+ {
+
+ this.bufferSize = Args.notNull(bufferSize, "bufferSize");
+ LOG.debug("Buffer size: '{}'", bufferSize);
+
+ kryo = createKryo();
+
+ internalInit(kryo);
+ }
+
+ protected Kryo createKryo()
+ {
+ return new KryoReflectionFactorySupport();
+ }
+
+ @Override
+ public byte[] serialize(final Object object)
+ {
+ LOG.debug("Going to serialize: '{}'", object);
+ ByteBuffer buffer = getBuffer(object);
+ kryo.writeClassAndObject(buffer, object);
+ byte[] data;
+ if (buffer.hasArray())
+ {
+ data = new byte[buffer.position()];
+ buffer.flip();
+ buffer.get(data);
+ }
+ else
+ {
+ LOG.error("Kryo wasn't able to serialize: '{}'", object);
+ data = null;
+ }
+
+ // release the memory for the buffer
+ buffer.clear();
+ buffer = null;
+ System.runFinalization();
+
+ return data;
+ }
+
+ @Override
+ public Object deserialize(byte[] data)
+ {
+ ByteBuffer buffer = ByteBuffer.wrap(data);
+ Object object = kryo.readClassAndObject(buffer);
+ LOG.debug("Deserialized: '{}'", object);
+
+ // release the memory for the buffer
+ buffer.clear();
+ buffer = null;
+ System.runFinalization();
+
+ return object;
+ }
+
+ /**
+ * Creates the buffer that will be used to serialize the {@code target}
+ *
+ * @param target
+ * the object that will be serialized. Can be used to decide dynamically what size to
+ * use
+ * @return the buffer that will be used to serialize the {@code target}
+ */
+ protected ByteBuffer getBuffer(Object target)
+ {
+ return ByteBuffer.allocate((int)bufferSize.bytes());
+ }
+
+ /**
+ * Configures {@link Kryo} with some custom {@link Serializer}s and registers some known Wicket
+ * classes which are known to be serialized sooner or later
+ *
+ * @param kryo
+ * the {@link Kryo} instance to configured
+ */
+ private void internalInit(final Kryo kryo)
+ {
+
+ kryo.register(Arrays.asList("").getClass(), new ArraysAsListSerializer(kryo));
+ kryo.register(Class.class, new ClassSerializer(kryo));
+ 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));
+ kryo.register(Collections.singleton("").getClass(), new CollectionsSingletonSetSerializer(
+ kryo));
+ kryo.register(Collections.singletonMap("", "").getClass(),
+ new CollectionsSingletonMapSerializer(kryo));
+ kryo.register(Currency.class, new CurrencySerializer(kryo));
+ kryo.register(GregorianCalendar.class, new GregorianCalendarSerializer());
+ kryo.register(InvocationHandler.class, new JdkProxySerializer(kryo));
+ kryo.register(StringBuffer.class, new StringBufferSerializer(kryo));
+ kryo.register(StringBuilder.class, new StringBuilderSerializer(kryo));
+ UnmodifiableCollectionsSerializer.registerSerializers(kryo);
+ SynchronizedCollectionsSerializer.registerSerializers(kryo);
+ kryo.register(CGLibProxySerializer.CGLibProxyMarker.class, new CGLibProxySerializer(kryo));
+ kryo.register(InvocationHandler.class, new JdkProxySerializer(kryo));
+ kryo.register(WicketChildListSerializer.CLASS, new WicketChildListSerializer(kryo));
+
+ kryo.setRegistrationOptional(true);
+ kryo.register(Panel.class);
+ kryo.register(WebPage.class);
+ kryo.register(WebMarkupContainer.class);
+ kryo.register(Link.class);
+ kryo.register(Label.class);
+ kryo.register(ListView.class);
+
+ init(kryo);
+ }
+
+ /**
+ * A method which can be overridden by users to do more configuration
+ *
+ * @param kryo
+ * the {@link Kryo} instance to configure
+ */
+ protected void init(final Kryo kryo)
+ {
+
+ }
+}
Oops, something went wrong.

0 comments on commit 41cb98a

Please sign in to comment.