2016-11-09 4 views
0

Nach dem Lesen vieler Beiträge fand ich keine Antwort auf mein Problem mit kryo.Kryo ClassNotFoundException plötzlich geworfen

Wir versuchen, Kryo (v4.0.0) in unserem System zu implementieren, das eine sehr große Menge von Nachrichten zwischen zwei Servern serialisiert/deserialisiert.

Unser Problem ist, dass die Serialisierung/Deserialisierung kann während mehrerer Minuten (so mehr als tausend Nachrichten) und plötzlich aufhören zu arbeiten, mit folgenden Ausnahme funktionieren:

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 

Sie können sehen, dass Kryo nicht gelingt Um den Klassennamen zu lesen (Klasse nicht gefunden:^AA ^]^A^@^A^B^C^_^C^C!^C^A59927910321794).

Meine serialize Klasse:

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); 
      } 
     } 
    } 
} 

Antwort

0

Wie ich weiß, ist die Kryo-Klasse nicht Thread-sicher. Wenn Sie es in einer gleichzeitigen Umgebung verwenden, müssen Sie jedes Mal eine neue Instanz erstellen. Wie folgt:

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

Ich habe ein ähnliches Problem auf diese Weise gelöst.

Verwandte Themen