2016-11-09 16 views
0

多くの投稿を読んだ後、私はkryoで私の問題の答えを見つけられませんでした。Kryo ClassNotFoundException突然投げた

私たちは、2台のサーバ間で非常に大量のメッセージをシリアライズ/デシリアライズするKryo(v4.0.0)を実装しようとしています。

私たちの問題は、シリアライズ/デシリアライゼーションのは、数分の間に正常に動作し(これ以上千以上のメッセージ)と、突然、次の例外を除いて動作するように停止することができるということです。

2016-11-09 13:23:32,968 [AMQP_consumer_blk-ic-p.tradair.com_TMSOutWL_TMSOutWL_streaming-1] ERROR Driver handleDelivery - 
com.esotericsoftware.kryo.KryoException: Unable to find class: ^AA^]^A^@^A^B^C^_^C ^C!^C^A59927910321794 
Serialization trace: 
payload (com.trade.common.messagebus.AMQPPacket) 
     at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java:160) ~[kryo-shaded-4.0.0.jar:?] 
     at com.esotericsoftware.kryo.util.DefaultClassResolver.readClass(DefaultClassResolver.java:133) ~[kryo-shaded-4.0.0.jar:?] 
     at com.esotericsoftware.kryo.Kryo.readClass(Kryo.java:693) ~[kryo-shaded-4.0.0.jar:?] 
     at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:118) ~[kryo-shaded-4.0.0.jar:?] 
     at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:540) ~[kryo-shaded-4.0.0.jar:?] 
     at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:813) ~[kryo-shaded-4.0.0.jar:?] 
     at com.tradair.common.serialization.kryo.KryoSerializer.deserialize(KryoSerializer.java:60) ~[common-4.7.3.12.jar:?] 
     at com.trade.common.messagebus.AbstractMessageBusConsumer$1.handleDelivery(AbstractMessageBusConsumer.java:106) ~[common-4.7.3.12.jar:?] 
     at com.rabbitmq.client.impl.ConsumerDispatcher$5.run(ConsumerDispatcher.java:144) ~[amqp-client-3.4.3.jar:?] 
     at com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:95) ~[amqp-client-3.4.3.jar:?] 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_40] 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_40] 
     at java.lang.Thread.run(Thread.java:745) [?:1.8.0_40] 
Caused by: java.lang.ClassNotFoundException: ^AA^]^A^@^A^B^C^_^C ^C!^C^A59927910321794 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[?:1.8.0_40] 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_40] 
     at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[?:1.8.0_40] 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_40] 
     at java.lang.Class.forName0(Native Method) ~[?:1.8.0_40] 
     at java.lang.Class.forName(Class.java:348) ~[?:1.8.0_40] 
     at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java:154) ~[kryo-shaded-4.0.0.jar:?] 
     ... 12 more 

あなたはKryoが成功しないことがわかりますクラス名を読み取る(クラス:^ AA ^]^A^@^A^B^C^_^C^C!^ C^A59927910321794)が見つかりません。

私のシリアル化クラス:

私が知っているように
public class KryoSerializer extends AbstractSerializer { 

    private Logger logger = LoggerFactory.getLogger(KryoSerializer.class); 
    protected Kryo kryo; 
    protected Output output; 
    protected Input input; 
    protected ByteArrayOutputStream bos; 
    protected ByteArrayInputStream bis; 

    public KryoSerializer(List<Class> list) { 
     kryo = new Kryo(); 
     kryo.setRegistrationRequired(false); 
     kryo.setReferences(true); 
     for (Class cl : list) { 
      kryo.register(cl); 
     } 
    } 

    @Override 
    public <T> byte[] serialize(T msg) { 
     try { 
      bos = new ByteArrayOutputStream(); 
      output = new Output(bos); 
      kryo.writeClassAndObject(output, msg); 
      output.flush(); 
      return bos.toByteArray(); 
     } finally { 
      try { 
       if (output != null) { 
        output.close(); 
       } 
       if (bos != null) { 
        bos.close(); 
       } 
      } catch (IOException eio) { 
       logger.warn("", eio); 
      } 
     } 
    } 

    @Override 
    public <T> T deserialize(byte[] bytesArray) { 
     try { 
      bis = new ByteArrayInputStream(bytesArray); 
      input = new Input(bis); 
      return (T) kryo.readClassAndObject(input); 
     } finally { 
      try { 
       if (input != null) { 
        input.close(); 
       } 
       if (bis != null) { 
        bis.close(); 
       } 
      } catch (IOException eio) { 
       logger.warn("", eio); 
      } 
     } 
    } 
} 

答えて

0

、Kryoクラスはスレッドセーフではありません。コンカレント環境で使用している場合は、毎回新しいインスタンスを作成する必要があります。このように:

bos = new ByteArrayOutputStream(); 
output = new Output(bos); 
new Kryo().writeClassAndObject(output, msg); 
output.flush(); 
return bos.toByteArray(); 

私はこのようにして同様の問題を解決しました。