2017-06-27 2 views
1

Ich brauche Hilfe, um eine Entity zu serialisieren, um sie von Akka Remote zu senden.akka Serialisierung ByteBuffer - java.lang.UnsupportedOperationException

Dies ist die Serializer Klasse:

@Override 
public void toBinary(Object o, ByteBuffer buf) { 

    byte[] bytes = null; 
    ByteArrayOutputStream bos = null; 
    ObjectOutputStream oos = null; 
    try { 
     bos = new ByteArrayOutputStream(); 
     oos = new ObjectOutputStream(bos); 
     oos.writeObject(o); 
     oos.flush(); 
     bytes = bos.toByteArray(); 
    } 
    catch(Exception e){ 
     //System.out.println(e.getStackTrace()); 
     e.printStackTrace(); 
    } 
    buf.put(bytes); 
} 

@Override 
    public Object fromBinary(ByteBuffer buf, String manifest) { 
     Object obj = null; 
     ByteArrayInputStream bis = null; 
     ObjectInputStream ois = null; 

     try { 
      bis = new ByteArrayInputStream(buf.array()); 
      ois = new ObjectInputStream(bis); 
      obj = ois.readObject(); 
     } 
     catch(Exception e){ 
      //System.out.println(e.getStackTrace()); 
      e.printStackTrace(); 
     } 
     return obj; 
    } 

Im erhält die folgende Ausnahme in Zeile 5

java.lang.UnsupportedOperationException 
    at java.nio.ByteBuffer.array(ByteBuffer.java:994) 
    at serializers.ExampleByteBufSerializer.fromBinary(ExampleByteBufSerializer.java:67) 
    at akka.serialization.Serialization.deserializeByteBuffer(Serialization.scala:190) 
    at akka.remote.MessageSerializer$.deserializeForArtery(MessageSerializer.scala:91) 
    at akka.remote.artery.Deserializer$$anon$3.onPush(Codecs.scala:620) 
    at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:499) 
    at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:401) 
    at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:571) 
    at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:457) 
    at akka.stream.impl.fusing.GraphInterpreterShell.processEvent(ActorGraphInterpreter.scala:546) 
    at akka.stream.impl.fusing.ActorGraphInterpreter.akka$stream$impl$fusing$ActorGraphInterpreter$$processEvent(ActorGraphInterpreter.scala:725) 
    at akka.stream.impl.fusing.ActorGraphInterpreter$$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:740) 
    at akka.actor.Actor$class.aroundReceive(Actor.scala:513) 
    at akka.stream.impl.fusing.ActorGraphInterpreter.aroundReceive(ActorGraphInterpreter.scala:650) 
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:527) 
    at akka.actor.ActorCell.invoke(ActorCell.scala:496) 
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257) 
    at akka.dispatch.Mailbox.run(Mailbox.scala:224) 
    at akka.dispatch.Mailbox.exec(Mailbox.scala:234) 
    at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) 
    at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) 
    at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) 
    at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) 

Dies wird die Nachricht Im an den Remote-Schauspieler zu senden:

public class Message2Serialize implements Serializable { 

    String nombre; 

    public Message2Serialize(String nombre) { 
     this.nombre = nombre; 
    } 

    public Message2Serialize() { 
    } 

    public String getNombre() { 
     return nombre; 
    } 


    public void setNombre(String nombre) { 
     this.nombre = nombre; 
    } 
} 

Das Seltsame ist, dass es auf eine Art funktioniert, wenn wir die Nachricht senden, funktioniert das im rec gut eptor:

ActorSelection selection = getContext().system().actorSelection("akka://[email protected]:25521/user/actors.MessageReceiverActor"); 
selection.tell(message2Serialize, getSelf()); 

Aber wenn wir an den Absender Schauspieler Wiedergabe mit getSender().tell(m, getSelf()); dann bekamen wir die Ausnahme.

Wir verwenden Java 1.8 und akka-remote_2.11: 2.5.3

Vielen Dank im Voraus! Rodri

+0

Haben Sie dies versucht, ohne einen benutzerdefinierten Serializer zu definieren? – thwiegan

+0

Ja, es funktioniert perfekt mit Standard-Java-Serializer –

+0

Jeder Grund, dass Sie die benutzerdefinierte dann verwenden? Afaik der Standard tut das gleiche wie Sie. – thwiegan

Antwort

0

Javadoc- Extrakt

@throws UnsupportedOperationException. Wenn dieser Puffer nicht von einem zugänglichen Array

die ByteBuffer scheint nicht vollständig initialisiert ... weiterhin die javadoc auch unterstützt wird, sagt, was

Invoke die {@link #hasArray hasArray zu tun } Methode vor dem Aufrufen dieser Methode, um sicherzustellen, dass dieser Puffer eine zugängliche Unterstützung Array hat.

+0

Das ist richtig, das Problem ist, dass es nicht initialisiert ist. Mit hasArray bekomme ich keine Ausnahme, aber ich bekomme keine Daten zur Deserialisierung. Es ist leer –

0

Durch Ändern Sie diese Zeile: bis = newByteArrayInputStream(arr); zu

byte[] arr = new byte[buf.remaining()]; 
buf.get(arr); 
bis = new ByteArrayInputStream(arr); 

Es funktioniert, aber ich bin nicht sicher, warum.

Verwandte Themen