/** * Copyright 2014 Comcast Cable Communications Management, LLC * * 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 com.comcast.viper.flume2storm.connection; import java.nio.ByteBuffer; import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.io.ByteBufferInputStream; import com.esotericsoftware.kryo.io.ByteBufferOutputStream; import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; import com.esotericsoftware.kryonet.Connection; import com.esotericsoftware.kryonet.FrameworkMessage.DiscoverHost; import com.esotericsoftware.kryonet.FrameworkMessage.KeepAlive; import com.esotericsoftware.kryonet.FrameworkMessage.Ping; import com.esotericsoftware.kryonet.FrameworkMessage.RegisterTCP; import com.esotericsoftware.kryonet.FrameworkMessage.RegisterUDP; import com.esotericsoftware.kryonet.KryoSerialization; /** * This {@link KryoSerialization} for KryoNet is used instead of the default * implementation because the later implementation throws a KryoException when * receiving data larger than 512 bytes. * * <pre> * com.esotericsoftware.kryo.KryoException: Buffer underflow. * at com.esotericsoftware.kryo.io.Input.require(Input.java:156) ~[kryo-2.21.jar:na] * at com.esotericsoftware.kryo.io.Input.readBytes(Input.java:317) ~[kryo-2.21.jar:na] * at com.esotericsoftware.kryo.io.Input.readBytes(Input.java:297) ~[kryo-2.21.jar:na] * at com.esotericsoftware.kryo.serializers.DefaultArraySerializers$ByteArraySerializer.read(DefaultArraySerializers.java:35) ~[kryo-2.21.jar:na] * at com.esotericsoftware.kryo.serializers.DefaultArraySerializers$ByteArraySerializer.read(DefaultArraySerializers.java:18) ~[kryo-2.21.jar:na] * at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:629) [kryo-2.21.jar:na] * </pre> * * See KryoNetBufferUnderflowTest in the test package of this module */ public class MyKryoSerialization extends KryoSerialization { private final Kryo kryo; private final Input input; private final Output output; private final ByteBufferInputStream byteBufferInputStream = new ByteBufferInputStream(); private final ByteBufferOutputStream byteBufferOutputStream = new ByteBufferOutputStream(); public MyKryoSerialization(int objectSize) { this(new Kryo(), objectSize); kryo.setReferences(false); kryo.setRegistrationRequired(true); } public MyKryoSerialization(Kryo kryo, int objectSize) { this.kryo = kryo; kryo.register(RegisterTCP.class); kryo.register(RegisterUDP.class); kryo.register(KeepAlive.class); kryo.register(DiscoverHost.class); kryo.register(Ping.class); input = new Input(byteBufferInputStream, objectSize); output = new Output(byteBufferOutputStream, objectSize); } public Kryo getKryo() { return kryo; } public synchronized void write(Connection connection, ByteBuffer buffer, Object object) { byteBufferOutputStream.setByteBuffer(buffer); kryo.getContext().put("connection", connection); kryo.writeClassAndObject(output, object); output.flush(); } public synchronized Object read(Connection connection, ByteBuffer buffer) { byteBufferInputStream.setByteBuffer(buffer); input.setInputStream(byteBufferInputStream); kryo.getContext().put("connection", connection); return kryo.readClassAndObject(input); } public void writeLength(ByteBuffer buffer, int length) { buffer.putInt(length); } public int readLength(ByteBuffer buffer) { return buffer.getInt(); } public int getLengthLength() { return 4; } }