diff --git a/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcConnection.java b/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcConnection.java index f457e426b..0ced410c4 100644 --- a/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcConnection.java +++ b/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcConnection.java @@ -225,6 +225,7 @@ public class RpcConnection { private class ResponseHolder { private Object response; private String error; + private Throwable exception; private RpcCallMessage msg; boolean received = false; @@ -235,6 +236,7 @@ public class RpcConnection { public synchronized void setResponse( RpcResponseMessage msg ) { this.response = msg.getResult(); this.error = msg.getError(); + this.exception = msg.getThrowable(); this.received = true; notifyAll(); } @@ -250,6 +252,9 @@ public class RpcConnection { if( error != null ) { throw new RuntimeException("Error calling remote procedure:" + msg + "\n" + error); } + if( exception != null ) { + throw new RuntimeException("Error calling remote procedure:" + msg, exception); + } return response; } diff --git a/jme3-networking/src/main/java/com/jme3/network/service/rpc/msg/RpcResponseMessage.java b/jme3-networking/src/main/java/com/jme3/network/service/rpc/msg/RpcResponseMessage.java index c8ca8083a..8e15514e7 100644 --- a/jme3-networking/src/main/java/com/jme3/network/service/rpc/msg/RpcResponseMessage.java +++ b/jme3-networking/src/main/java/com/jme3/network/service/rpc/msg/RpcResponseMessage.java @@ -34,6 +34,7 @@ package com.jme3.network.service.rpc.msg; import com.jme3.network.AbstractMessage; import com.jme3.network.serializing.Serializable; +import com.jme3.network.serializing.Serializer; import java.io.PrintWriter; import java.io.StringWriter; @@ -50,6 +51,7 @@ public class RpcResponseMessage extends AbstractMessage { private long msgId; private Object result; private String error; + private Object exception; // if it was serializable public RpcResponseMessage() { } @@ -61,12 +63,31 @@ public class RpcResponseMessage extends AbstractMessage { public RpcResponseMessage( long msgId, Throwable t ) { this.msgId = msgId; - - StringWriter sOut = new StringWriter(); - PrintWriter out = new PrintWriter(sOut); - t.printStackTrace(out); - out.close(); - this.error = sOut.toString(); + + // See if the exception is serializable + if( isSerializable(t) ) { + // Can send the exception itself + this.exception = t; + } else { + // We'll compose all of the info into a string + StringWriter sOut = new StringWriter(); + PrintWriter out = new PrintWriter(sOut); + t.printStackTrace(out); + out.close(); + this.error = sOut.toString(); + } + } + + public static boolean isSerializable( Throwable error ) { + if( error == null ) { + return false; + } + for( Throwable t = error; t != null; t = t.getCause() ) { + if( Serializer.getExactSerializerRegistration(t.getClass()) == null ) { + return false; + } + } + return true; } public long getMessageId() { @@ -81,10 +102,15 @@ public class RpcResponseMessage extends AbstractMessage { return error; } + public Throwable getThrowable() { + return (Throwable)exception; + } + @Override public String toString() { return getClass().getSimpleName() + "[#" + msgId + ", result=" + result + (error != null ? ", error=" + error : "") + + (exception != null ? ", exception=" + exception : "") + "]"; } }