This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new b6bed70  Throwables not always thrown from @Remote methods.
b6bed70 is described below

commit b6bed7012babe1ec941efb9da4ce7420f335dd3e
Author: JamesBognar <james.bog...@salesforce.com>
AuthorDate: Mon Jun 15 12:43:24 2020 -0400

    Throwables not always thrown from @Remote methods.
---
 .../org/apache/juneau/internal/ThrowableUtils.java |  32 ++++
 .../rest/test/client/ThirdPartyProxyTest.java      |   6 +-
 .../juneau/rest/client2/InterfaceProxyTest.java    |   4 +-
 .../apache/juneau/rest/client2/RemotesTest.java    |  64 +++----
 .../juneau/rest/client2/RestCallException.java     |  64 ++-----
 .../org/apache/juneau/rest/client2/RestClient.java | 209 ++++++++++++---------
 6 files changed, 203 insertions(+), 176 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ThrowableUtils.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ThrowableUtils.java
index ac7bc4b..227c8f3 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ThrowableUtils.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ThrowableUtils.java
@@ -15,6 +15,7 @@ package org.apache.juneau.internal;
 import java.text.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.reflect.*;
 
 /**
  * Various utility methods for creating and working with throwables.
@@ -117,4 +118,35 @@ public class ThrowableUtils {
                }
                return null;
        }
+
+       /**
+        * Given a list of available throwable types, attempts to create and 
throw the exception based on name.
+        *
+        * @param name The exception name.  Can be a simple name or 
fully-qualified.
+        * @param message The exception message passed to the exception 
constructor.
+        * @param throwables The list of available throwable classes to choose 
from.
+        * @throws Throwable The thrown exception if it was possible to create.
+        */
+       public static void throwException(String name, String message, 
Class<?>...throwables) throws Throwable {
+               if (name != null)
+                       for (Class<?> t : throwables)
+                               if (t.getName().endsWith(name))
+                                       doThrow(t, message);
+       }
+
+       private static void doThrow(Class<?> t, String msg) throws Throwable {
+               ConstructorInfo c = null;
+               ClassInfo ci = ClassInfo.of(t);
+               if (msg != null) {
+                       c = ci.getPublicConstructor(String.class);
+                       if (c != null)
+                               throw c.<Throwable>invoke(msg);
+                       c = ci.getPublicConstructor(Object.class);
+                       if (c != null)
+                               throw c.<Throwable>invoke(msg);
+               }
+               c = ci.getPublicConstructor();
+               if (c != null)
+                       throw c.<Throwable>invoke();
+       }
 }
diff --git 
a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java
 
b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java
index 2b65e84..bd7053a 100644
--- 
a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java
+++ 
b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java
@@ -66,7 +66,7 @@ public class ThirdPartyProxyTest extends RestTestcase {
        public ThirdPartyProxyTest(String label, Serializer serializer, Parser 
parser) {
                proxy = getCached(label, ThirdPartyProxy.class);
                if (proxy == null) {
-                       this.proxy = getClient(label, serializer, 
parser).builder().partSerializer(UonSerializer.DEFAULT.builder().addBeanTypes().addRootType().build()).build().getRemote(ThirdPartyProxy.class,
 null, serializer, parser);
+                       this.proxy = getClient(label, serializer, 
parser).builder().ignoreErrors().partSerializer(UonSerializer.DEFAULT.builder().addBeanTypes().addRootType().build()).build().getRemote(ThirdPartyProxy.class,
 null, serializer, parser);
                        cache(label, proxy);
                }
        }
@@ -2352,7 +2352,7 @@ public class ThirdPartyProxyTest extends RestTestcase {
                // Various primitives
 
                @RemoteMethod(method="POST", path="/setInt")
-               void setInt(@Body int x);
+               void setInt(@Body int x) throws AssertionError;
 
                @RemoteMethod(method="POST", path="/setInteger")
                void setInteger(@Body Integer x);
@@ -2370,7 +2370,7 @@ public class ThirdPartyProxyTest extends RestTestcase {
                void setString(@Body String x);
 
                @RemoteMethod(method="POST", path="/setNullString")
-               void setNullString(@Body String x);
+               void setNullString(@Body String x) throws AssertionError;
 
                @RemoteMethod(method="POST", path="/setInt3dArray")
                String setInt3dArray(@Body int[][][] x, 
@org.apache.juneau.http.annotation.Query("I") int i);
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/InterfaceProxyTest.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/InterfaceProxyTest.java
index f87f012..1e4b734 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/InterfaceProxyTest.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/InterfaceProxyTest.java
@@ -142,13 +142,13 @@ public class InterfaceProxyTest {
 
                // Various primitives
                void setNothing();
-               void setInt(int x);
+               void setInt(int x) throws AssertionError;
                void setInteger(Integer x);
                void setBoolean(boolean x);
                void setFloat(float x);
                void setFloatObject(Float x);
                void setString(String x);
-               void setNullString(String x);
+               void setNullString(String x) throws AssertionError;
                void setInt3dArray(int[][][] x);
                void setInteger3dArray(Integer[][][] x);
                void setString3dArray(String[][][] x);
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemotesTest.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemotesTest.java
index 068e18b..a66548a 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemotesTest.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemotesTest.java
@@ -374,36 +374,36 @@ public class RemotesTest {
                }
        }
 
-//     @Test
-//     public void c04_rethrownException() throws Exception {
-//             C01i x = MockRestClient
-//                     .create(C01.class)
-//                     .json()
-//                     .build()
-//                     .getRemote(C01i.class);
-//
-//             try {
-//                     x.c04();
-//                     fail();
-//             } catch (C01Exception e) {
-//                     assertEquals("foo", e.getLocalizedMessage());
-//             }
-//     }
-//
-//
-//     @Test
-//     public void c05_rethrownUndefinedException() throws Exception {
-//             C01i x = MockRestClient
-//                     .create(C01.class)
-//                     .json()
-//                     .build()
-//                     .getRemote(C01i.class);
-//
-//             try {
-//                     x.c05();
-//                     fail();
-//             } catch (RuntimeException e) {
-//                     assertEquals("foo", e.getLocalizedMessage());
-//             }
-//     }
+       @Test
+       public void c04_rethrownException() throws Exception {
+               C01i x = MockRestClient
+                       .create(C01.class)
+                       .json()
+                       .build()
+                       .getRemote(C01i.class);
+
+               try {
+                       x.c04();
+                       fail();
+               } catch (C01Exception e) {
+                       assertEquals("foo", e.getLocalizedMessage());
+               }
+       }
+
+
+       @Test
+       public void c05_rethrownUndefinedException() throws Exception {
+               C01i x = MockRestClient
+                       .create(C01.class)
+                       .json()
+                       .build()
+                       .getRemote(C01i.class);
+
+               try {
+                       x.c05();
+                       fail();
+               } catch (RuntimeException e) {
+                       assertTrue(e.getLocalizedMessage().contains("foo"));
+               }
+       }
 }
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallException.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallException.java
index f178406..f28c76c 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallException.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallException.java
@@ -23,7 +23,6 @@ import org.apache.http.*;
 import org.apache.http.client.*;
 import org.apache.http.util.*;
 import org.apache.juneau.internal.*;
-import org.apache.juneau.reflect.*;
 
 /**
  * Exception representing a <c>400+</c> HTTP response code against a remote 
resource or other exception.
@@ -37,7 +36,6 @@ public final class RestCallException extends HttpException {
        HttpResponseException e;
        private RestResponse restResponse;
 
-       @SuppressWarnings("unused")
        private String serverExceptionName, serverExceptionMessage, 
serverExceptionTrace;
 
        /**
@@ -138,54 +136,30 @@ public final class RestCallException extends 
HttpException {
        }
 
        /**
-        * Tries to reconstruct and re-throw the server-side exception.
+        * Returns the value of the <js>"Exception-Name"</js> header on the 
response.
         *
-        * <p>
-        * The exception is based on the following HTTP response headers:
-        * <ul>
-        *      <li><c>Exception-Name:</c> - The full class name of the 
exception.
-        *      <li><c>Exception-Message:</c> - The message returned by {@link 
Throwable#getMessage()}.
-        *      <li><c>Exception-Trace:</c> - The stack trace of the exception 
returned by {@link Throwable#printStackTrace()}.
-        * </ul>
-        *
-        * <p>
-        * Does nothing if the server-side exception could not be reconstructed.
-        *
-        * <p>
-        * Currently only supports <c>Throwables</c> with either a public 
no-arg constructor
-        * or a public constructor that takes in a simple string message.
+        * @return The value of the <js>"Exception-Name"</js> header on the 
response, or <jk>null</jk> if not found.
+        */
+       public String getServerExceptionName() {
+               return serverExceptionName;
+       }
+
+       /**
+        * Returns the value of the <js>"Exception-Message"</js> header on the 
response.
         *
-        * @param cl The classloader to use to resolve the throwable class name.
-        * @param throwables The possible throwables.
-        * @throws Throwable If the throwable could be reconstructed.
+        * @return The value of the <js>"Exception-Message"</js> header on the 
response, or <jk>null</jk> if not found.
         */
-       protected void throwServerException(ClassLoader cl, 
Class<?>...throwables) throws Throwable {
-               if (serverExceptionName != null) {
-                       for (Class<?> t : throwables)
-                               if (t.getName().endsWith(serverExceptionName))
-                                       doThrow(t, serverExceptionMessage);
-                       try {
-                               ClassInfo t = 
ClassInfo.of(cl.loadClass(serverExceptionName));
-                               if (t.isChildOf(RuntimeException.class) || 
t.isChildOf(Error.class))
-                                       doThrow(t.inner(), 
serverExceptionMessage);
-                       } catch (ClassNotFoundException e2) { /* Ignore */ }
-               }
+       public String getServerExceptionMessage() {
+               return serverExceptionMessage;
        }
 
-       private void doThrow(Class<?> t, String msg) throws Throwable {
-               ConstructorInfo c = null;
-               ClassInfo ci = ClassInfo.of(t);
-               if (msg != null) {
-                       c = ci.getPublicConstructor(String.class);
-                       if (c != null)
-                               throw c.<Throwable>invoke(msg);
-                       c = ci.getPublicConstructor(Object.class);
-                       if (c != null)
-                               throw c.<Throwable>invoke(msg);
-               }
-               c = ci.getPublicConstructor();
-               if (c != null)
-                       throw c.<Throwable>invoke();
+       /**
+        * Returns the value of the <js>"Exception-Trace"</js> header on the 
response.
+        *
+        * @return The value of the <js>"Exception-Trace"</js> header on the 
response, or <jk>null</jk> if not found.
+        */
+       public String getServerExceptionTrace() {
+               return serverExceptionTrace;
        }
 
        /**
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
index 39d1893..e74a59c 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
@@ -2969,86 +2969,89 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                                                String httpMethod = 
rmm.getHttpMethod();
                                                HttpPartSerializerSession s = 
getPartSerializerSession();
 
-                                               try {
-                                                       RestRequest rc = 
request(httpMethod, url, hasContent(httpMethod));
-
-                                                       
rc.serializer(serializer);
-                                                       rc.parser(parser);
-
-                                                       for (RemoteMethodArg a 
: rmm.getPathArgs())
-                                                               
rc.path(a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer(s));
-
-                                                       for (RemoteMethodArg a 
: rmm.getQueryArgs())
-                                                               
rc.query(a.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), 
args[a.getIndex()], a.getSchema(), a.getSerializer(s));
-
-                                                       for (RemoteMethodArg a 
: rmm.getFormDataArgs())
-                                                               
rc.formData(a.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, 
a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer(s));
-
-                                                       for (RemoteMethodArg a 
: rmm.getHeaderArgs())
-                                                               
rc.header(a.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), 
args[a.getIndex()], a.getSchema(), a.getSerializer(s));
-
-                                                       RemoteMethodArg ba = 
rmm.getBodyArg();
-                                                       if (ba != null)
-                                                               
rc.body(args[ba.getIndex()], ba.getSchema());
-
-                                                       if 
(rmm.getRequestArgs().length > 0) {
-                                                               for 
(RemoteMethodBeanArg rmba : rmm.getRequestArgs()) {
-                                                                       
RequestBeanMeta rbm = rmba.getMeta();
-                                                                       Object 
bean = args[rmba.getIndex()];
-                                                                       if 
(bean != null) {
-                                                                               
for (RequestBeanPropertyMeta p : rbm.getProperties()) {
-                                                                               
        Object val = p.getGetter().invoke(bean);
-                                                                               
        HttpPartType pt = p.getPartType();
-                                                                               
        HttpPartSerializerSession ps = p.getSerializer(s);
-                                                                               
        String pn = p.getPartName();
-                                                                               
        HttpPartSchema schema = p.getSchema();
-                                                                               
        EnumSet<AddFlag> flags = schema.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : 
DEFAULT_FLAGS;
-                                                                               
        if (pt == PATH)
-                                                                               
                rc.path(pn, val, schema, p.getSerializer(s));
-                                                                               
        else if (val != null) {
-                                                                               
                if (pt == QUERY)
-                                                                               
                        rc.query(flags, pn, val, schema, ps);
-                                                                               
                else if (pt == FORMDATA)
-                                                                               
                        rc.formData(flags, pn, val, schema, ps);
-                                                                               
                else if (pt == HEADER)
-                                                                               
                        rc.header(flags, pn, val, schema, ps);
-                                                                               
                else /* (pt == HttpPartType.BODY) */
-                                                                               
                        rc.body(val, schema);
-                                                                               
        }
+                                               RestRequest rc = 
request(httpMethod, url, hasContent(httpMethod));
+
+                                               rc.serializer(serializer);
+                                               rc.parser(parser);
+
+                                               for (RemoteMethodArg a : 
rmm.getPathArgs())
+                                                       rc.path(a.getName(), 
args[a.getIndex()], a.getSchema(), a.getSerializer(s));
+
+                                               for (RemoteMethodArg a : 
rmm.getQueryArgs())
+                                                       
rc.query(a.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), 
args[a.getIndex()], a.getSchema(), a.getSerializer(s));
+
+                                               for (RemoteMethodArg a : 
rmm.getFormDataArgs())
+                                                       
rc.formData(a.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, 
a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer(s));
+
+                                               for (RemoteMethodArg a : 
rmm.getHeaderArgs())
+                                                       
rc.header(a.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), 
args[a.getIndex()], a.getSchema(), a.getSerializer(s));
+
+                                               RemoteMethodArg ba = 
rmm.getBodyArg();
+                                               if (ba != null)
+                                                       
rc.body(args[ba.getIndex()], ba.getSchema());
+
+                                               if (rmm.getRequestArgs().length 
> 0) {
+                                                       for 
(RemoteMethodBeanArg rmba : rmm.getRequestArgs()) {
+                                                               RequestBeanMeta 
rbm = rmba.getMeta();
+                                                               Object bean = 
args[rmba.getIndex()];
+                                                               if (bean != 
null) {
+                                                                       for 
(RequestBeanPropertyMeta p : rbm.getProperties()) {
+                                                                               
Object val = p.getGetter().invoke(bean);
+                                                                               
HttpPartType pt = p.getPartType();
+                                                                               
HttpPartSerializerSession ps = p.getSerializer(s);
+                                                                               
String pn = p.getPartName();
+                                                                               
HttpPartSchema schema = p.getSchema();
+                                                                               
EnumSet<AddFlag> flags = schema.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : 
DEFAULT_FLAGS;
+                                                                               
if (pt == PATH)
+                                                                               
        rc.path(pn, val, schema, p.getSerializer(s));
+                                                                               
else if (val != null) {
+                                                                               
        if (pt == QUERY)
+                                                                               
                rc.query(flags, pn, val, schema, ps);
+                                                                               
        else if (pt == FORMDATA)
+                                                                               
                rc.formData(flags, pn, val, schema, ps);
+                                                                               
        else if (pt == HEADER)
+                                                                               
                rc.header(flags, pn, val, schema, ps);
+                                                                               
        else /* (pt == HttpPartType.BODY) */
+                                                                               
                rc.body(val, schema);
                                                                                
}
                                                                        }
                                                                }
                                                        }
+                                               }
 
-                                                       RemoteMethodReturn rmr 
= rmm.getReturns();
-                                                       if (rmr.isFuture()) {
-                                                               return 
getExecutorService(true).submit(new Callable<Object>() {
-                                                                       
@Override
-                                                                       public 
Object call() throws Exception {
-                                                                               
return executeRemote(rc, method, rmr);
+                                               RemoteMethodReturn rmr = 
rmm.getReturns();
+                                               if (rmr.isFuture()) {
+                                                       return 
getExecutorService(true).submit(new Callable<Object>() {
+                                                               @Override
+                                                               public Object 
call() throws Exception {
+                                                                       try {
+                                                                               
return executeRemote(interfaceClass, rc, method, rmm);
+                                                                       } catch 
(Exception e) {
+                                                                               
throw e;
+                                                                       } catch 
(Throwable e) {
+                                                                               
throw new RuntimeException(e);
                                                                        }
-                                                               });
-                                                       } else if 
(rmr.isCompletableFuture()) {
-                                                               
CompletableFuture<Object> cf = new CompletableFuture<>();
-                                                               
getExecutorService(true).submit(new Callable<Object>() {
-                                                                       
@Override
-                                                                       public 
Object call() throws Exception {
-                                                                               
cf.complete(executeRemote(rc, method, rmr));
+                                                               }
+                                                       });
+                                               } else if 
(rmr.isCompletableFuture()) {
+                                                       
CompletableFuture<Object> cf = new CompletableFuture<>();
+                                                       
getExecutorService(true).submit(new Callable<Object>() {
+                                                               @Override
+                                                               public Object 
call() throws Exception {
+                                                                       try {
+                                                                               
cf.complete(executeRemote(interfaceClass, rc, method, rmm));
                                                                                
return null;
+                                                                       } catch 
(Exception e) {
+                                                                               
throw e;
+                                                                       } catch 
(Throwable e) {
+                                                                               
throw new RuntimeException(e);
                                                                        }
-                                                               });
-                                                               return cf;
-                                                       }
-
-                                                       return 
executeRemote(rc, method, rmr);
-
-                                               } catch (RestCallException e) {
-                                                       // Try to throw 
original exception if possible.
-                                                       
e.throwServerException(interfaceClass.getClassLoader(), rmm.getExceptions());
-                                                       throw new 
RuntimeException(e);
-                                               } catch (Exception e) {
-                                                       throw new 
RuntimeException(e);
+                                                               }
+                                                       });
+                                                       return cf;
                                                }
+
+                                               return 
executeRemote(interfaceClass, rc, method, rmm);
                                        }
                        });
                } catch (Exception e) {
@@ -3056,28 +3059,46 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                }
        }
 
-       Object executeRemote(RestRequest rc, Method method, RemoteMethodReturn 
rmr) throws RestCallException {
-               if (rmr.getReturnValue() == RemoteReturn.NONE) {
-                       rc.complete();
-                       return null;
-               } else if (rmr.getReturnValue() == RemoteReturn.STATUS) {
-                       rc.ignoreErrors();
-                       int returnCode = rc.complete().getStatusCode();
-                       Class<?> rt = method.getReturnType();
-                       if (rt == Integer.class || rt == int.class)
-                               return returnCode;
-                       if (rt == Boolean.class || rt == boolean.class)
-                               return returnCode < 400;
-                       throw new RestCallException("Invalid return type on 
method annotated with @RemoteMethod(returns=HTTP_STATUS).  Only integer and 
booleans types are valid.");
-               } else if (rmr.getReturnValue() == RemoteReturn.BEAN) {
-                       rc.ignoreErrors();
-                       return rc.run().as(rmr.getResponseBeanMeta());
-               } else {
-                       rc.ignoreErrors();
-                       Object v = rc.run().getBody().as(rmr.getReturnType());
-                       if (v == null && method.getReturnType().isPrimitive())
-                               v = 
ClassInfo.of(method.getReturnType()).getPrimitiveDefault();
-                       return v;
+       Object executeRemote(Class<?> interfaceClass, RestRequest rc, Method 
method, RemoteMethodMeta rmm) throws Throwable {
+               RemoteMethodReturn rmr = rmm.getReturns();
+
+               try {
+                       Object ret = null;
+                       RestResponse res = null;
+                       if (rmr.getReturnValue() == RemoteReturn.NONE) {
+                               res = rc.complete();
+                       } else if (rmr.getReturnValue() == RemoteReturn.STATUS) 
{
+                               res = rc.complete();
+                               int returnCode = res.getStatusCode();
+                               Class<?> rt = method.getReturnType();
+                               if (rt == Integer.class || rt == int.class)
+                                       ret = returnCode;
+                               else if (rt == Boolean.class || rt == 
boolean.class)
+                                       ret = returnCode < 400;
+                               else
+                                       throw new RestCallException("Invalid 
return type on method annotated with @RemoteMethod(returns=HTTP_STATUS).  Only 
integer and booleans types are valid.");
+                       } else if (rmr.getReturnValue() == RemoteReturn.BEAN) {
+                               rc.ignoreErrors();
+                               res = rc.run();
+                               ret = res.as(rmr.getResponseBeanMeta());
+                       } else {
+                               Class<?> rt = method.getReturnType();
+                               if (Throwable.class.isAssignableFrom(rt))
+                                       rc.ignoreErrors();
+                               res = rc.run();
+                               Object v = 
res.getBody().as(rmr.getReturnType());
+                               if (v == null && rt.isPrimitive())
+                                       v = 
ClassInfo.of(rt).getPrimitiveDefault();
+                               if 
(rt.getName().equals(res.getStringHeader("Exception-Name")))
+                                       res.removeHeaders("Exception-Name");
+                               ret = v;
+                       }
+
+                       
ThrowableUtils.throwException(res.getStringHeader("Exception-Name"), 
res.getStringHeader("Exception-Message"), rmm.getExceptions());
+                       return ret;
+               } catch (RestCallException e) {
+                       
ThrowableUtils.throwException(e.getServerExceptionName(), 
e.getServerExceptionMessage(), rmm.getExceptions());
+                       throw new RuntimeException(e);
                }
        }
 
@@ -3196,7 +3217,7 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
 
                                                } catch (RestCallException e) {
                                                        // Try to throw 
original exception if possible.
-                                                       
e.throwServerException(interfaceClass.getClassLoader(), 
method.getExceptionTypes());
+                                                       
ThrowableUtils.throwException(e.getServerExceptionName(), 
e.getServerExceptionMessage(), method.getExceptionTypes());
                                                        throw new 
RuntimeException(e);
                                                } catch (Exception e) {
                                                        throw new 
RuntimeException(e);

Reply via email to