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 75f178d  RestClient tests.
75f178d is described below

commit 75f178d6505b86d7cfa8e610abf93a85b0ac0842
Author: JamesBognar <[email protected]>
AuthorDate: Tue Jun 9 16:07:21 2020 -0400

    RestClient tests.
---
 .../java/org/apache/juneau/BasicException.java     |  13 +
 .../juneau/BasicIllegalArgumentException.java      |  12 +
 .../org/apache/juneau/BasicRuntimeException.java   |  13 +
 .../main/java/org/apache/juneau/BeanRegistry.java  |   9 +-
 .../juneau/http/exception/HttpException.java       |   7 +-
 .../org/apache/juneau/internal/ThrowableUtils.java |  18 ++
 .../org/apache/juneau/reflect/ConstructorInfo.java |   2 +
 .../rest/client2/RestClientMarshallsTest.java      |   3 +-
 .../apache/juneau/rest/client2/RestClientTest.java | 338 +++++++++++++++++++++
 .../juneau/rest/client2/RestCallException.java     |   9 +-
 .../org/apache/juneau/rest/client2/RestClient.java |  18 +-
 .../apache/juneau/rest/mock2/MockRestClient.java   |   7 +-
 .../apache/juneau/rest/HttpRuntimeException.java   |   3 +-
 .../java/org/apache/juneau/rest/RestContext.java   |   4 +-
 .../org/apache/juneau/rest/RestContextBuilder.java |   3 +-
 .../juneau/rest/RestMethodContextBuilder.java      |   2 +-
 .../org/apache/juneau/rest/RestParamDefaults.java  |   4 +-
 .../apache/juneau/rest/RestServletException.java   |  26 +-
 .../org/apache/juneau/rest/SwaggerGenerator.java   |   2 +-
 19 files changed, 455 insertions(+), 38 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicException.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicException.java
index 2c6fb28..4e0bc03 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicException.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicException.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.internal.StringUtils.*;
 
 import java.text.*;
 
+import org.apache.juneau.internal.*;
+
 /**
  * Subclass of non-runtime exceptions that take in a message and zero or more 
arguments.
  */
@@ -53,4 +55,15 @@ public class BasicException extends Exception {
        public BasicException(Throwable causedBy) {
                this(causedBy, causedBy.getLocalizedMessage());
        }
+
+       /**
+        * Same as {@link #getCause()} but searches the throwable chain for an 
exception of the specified type.
+        *
+        * @param c The throwable type to search for.
+        * @param <T> The throwable type to search for.
+        * @return The exception, or <jk>null</jk> if not found.
+        */
+       public <T extends Throwable> T getCause(Class<T> c) {
+               return ThrowableUtils.getCause(c, this);
+       }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicIllegalArgumentException.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicIllegalArgumentException.java
index 7f976a3..08b408d 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicIllegalArgumentException.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicIllegalArgumentException.java
@@ -16,6 +16,7 @@ import static org.apache.juneau.internal.StringUtils.*;
 
 import java.text.*;
 
+import org.apache.juneau.internal.*;
 import org.apache.juneau.reflect.*;
 
 /**
@@ -57,4 +58,15 @@ public class BasicIllegalArgumentException extends 
IllegalArgumentException {
                if (! m.argsOnlyOfType(args))
                        throw new BasicIllegalArgumentException("Invalid 
arguments passed to method {0}.  Only arguments of type {1} are allowed.", m, 
args);
        }
+
+       /**
+        * Same as {@link #getCause()} but searches the throwable chain for an 
exception of the specified type.
+        *
+        * @param c The throwable type to search for.
+        * @param <T> The throwable type to search for.
+        * @return The exception, or <jk>null</jk> if not found.
+        */
+       public <T extends Throwable> T getCause(Class<T> c) {
+               return ThrowableUtils.getCause(c, this);
+       }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicRuntimeException.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicRuntimeException.java
index 24d5e6a..a649fe5 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicRuntimeException.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicRuntimeException.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.internal.StringUtils.*;
 
 import java.text.*;
 
+import org.apache.juneau.internal.*;
+
 /**
  * Subclass of runtime exceptions that take in a message and zero or more 
arguments.
  */
@@ -60,4 +62,15 @@ public class BasicRuntimeException extends RuntimeException {
                        return cause.getMessage();
                return def;
        }
+
+       /**
+        * Same as {@link #getCause()} but searches the throwable chain for an 
exception of the specified type.
+        *
+        * @param c The throwable type to search for.
+        * @param <T> The throwable type to search for.
+        * @return The exception, or <jk>null</jk> if not found.
+        */
+       public <T extends Throwable> T getCause(Class<T> c) {
+               return ThrowableUtils.getCause(c, this);
+       }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanRegistry.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanRegistry.java
index 9fc8667..0627f9f 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanRegistry.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanRegistry.java
@@ -89,10 +89,13 @@ public class BeanRegistry {
                                                addToMap(typeName, val);
                                        }
                                } else {
-                                       Bean b = 
ci.getLastAnnotation(Bean.class, beanContext);
-                                       if (b == null || b.typeName().isEmpty())
+                                       String typeName = null;
+                                       for (Bean b : 
ci.getAnnotations(Bean.class, beanContext))
+                                               if (! b.typeName().isEmpty())
+                                                       typeName = b.typeName();
+                                       if (typeName == null)
                                                throw new 
BeanRuntimeException("Class ''{0}'' was passed to BeanRegistry but it doesn't 
have a @Bean(typeName) annotation defined.", c.getName());
-                                       addToMap(b.typeName(), 
beanContext.getClassMeta(c));
+                                       addToMap(typeName, 
beanContext.getClassMeta(c));
                                }
                        }
                } catch (BeanRuntimeException e) {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpException.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpException.java
index 740a4e8..c4e414d 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpException.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpException.java
@@ -18,6 +18,7 @@ import java.lang.reflect.*;
 import java.text.*;
 import java.util.*;
 
+import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.http.annotation.*;
@@ -30,7 +31,7 @@ import org.apache.juneau.internal.*;
  * REST methods on subclasses of <c>RestServlet</c> can throw this exception 
to trigger an HTTP status other than the
  * automatically-generated <c>404</c>, <c>405</c>, and <c>500</c> statuses.
  */
-public class HttpException extends RuntimeException {
+public class HttpException extends BasicRuntimeException {
 
        private static final long serialVersionUID = 1L;
 
@@ -46,7 +47,7 @@ public class HttpException extends RuntimeException {
         * @param args Optional {@link MessageFormat}-style arguments.
         */
        public HttpException(Throwable cause, int status, String msg, 
Object...args) {
-               super(message(cause, msg, args), cause);
+               super(cause, message(cause, msg, args));
                this.status = status;
        }
 
@@ -56,7 +57,7 @@ public class HttpException extends RuntimeException {
         * @param msg The status message.
         */
        public HttpException(String msg) {
-               super(msg, null);
+               super((Throwable)null, msg);
        }
 
        private static String message(Throwable cause, String msg, 
Object...args) {
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 a5ea31c..ac7bc4b 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
@@ -99,4 +99,22 @@ public class ThrowableUtils {
                t.printStackTrace();
                throw new BasicAssertionError(t, "Throwable did not contain the 
expected message.  Message=[{0}]", msg);
        }
+
+       /**
+        * Same as {@link Throwable#getCause()} but searches the throwable 
chain for an exception of the specified type.
+        *
+        * @param c The throwable type to search for.
+        * @param <T> The throwable type to search for.
+        * @param t The throwable to search.
+        * @return The exception, or <jk>null</jk> if not found.
+        */
+       @SuppressWarnings("unchecked")
+       public static <T extends Throwable> T getCause(Class<T> c, Throwable t) 
{
+               while (t != null) {
+                       t = t.getCause();
+                       if (c.isInstance(t))
+                               return (T)t;
+               }
+               return null;
+       }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ConstructorInfo.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ConstructorInfo.java
index 4de094b..8b93b7b 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ConstructorInfo.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ConstructorInfo.java
@@ -137,6 +137,8 @@ public final class ConstructorInfo extends ExecutableInfo 
implements Comparable<
        public <T> T invoke(Object...args) throws ExecutableException {
                try {
                        return (T)c.newInstance(args);
+               } catch (InvocationTargetException e) {
+                       throw new ExecutableException(e.getTargetException());
                } catch (Exception e) {
                        throw new ExecutableException(e);
                }
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientMarshallsTest.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientMarshallsTest.java
index 9e91c3b..b79ee1b 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientMarshallsTest.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientMarshallsTest.java
@@ -448,9 +448,10 @@ public class RestClientMarshallsTest {
        }
 
        @Test
-       public void d03_nullMarshall() throws Exception {
+       public void d03_nullMarshalls() throws Exception {
                MockRestClient
                        .create(A.class)
+                       .marshall(null)
                        .marshalls(Json.DEFAULT, null)
                        .build()
                        .post("/a01", bean)
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientTest.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientTest.java
index 5ef5f42..c3ad079 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientTest.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientTest.java
@@ -14,6 +14,7 @@ package org.apache.juneau.rest.client2;
 
 import static org.junit.Assert.*;
 import static org.junit.runners.MethodSorters.*;
+import static org.apache.juneau.rest.client2.RestClient.*;
 import static org.apache.juneau.testutils.TestUtils.*;
 
 import java.io.*;
@@ -86,14 +87,38 @@ public class RestClientTest {
        @Rest
        public static class A extends BasicRest {
                @RestMethod(path="/bean")
+               public Bean getBean() {
+                       return bean;
+               }
+               @RestMethod(path="/bean")
                public Bean postBean(@Body Bean b) {
                        return b;
                }
+               @RestMethod(path="/bean")
+               public Bean putBean(@Body Bean b) {
+                       return b;
+               }
+               @RestMethod(path="/bean")
+               public Bean deleteBean() {
+                       return bean;
+               }
+               @RestMethod(path="/bean")
+               public Bean optionsBean() {
+                       return bean;
+               }
+               @RestMethod(path="/bean")
+               public Bean headBean() {
+                       return bean;
+               }
                @RestMethod(path="/echo")
                public String getEcho(org.apache.juneau.rest.RestRequest req) {
                        return req.toString();
                }
                @RestMethod(path="/echo")
+               public String putEcho(org.apache.juneau.rest.RestRequest req) {
+                       return req.toString();
+               }
+               @RestMethod(path="/echo")
                public String postEcho(org.apache.juneau.rest.RestRequest req) {
                        return req.toString();
                }
@@ -117,8 +142,13 @@ public class RestClientTest {
                public Reader postFormData(org.apache.juneau.rest.RestRequest 
req) {
                        return new 
StringReader(req.getFormData().asQueryString());
                }
+               @RestMethod(path="/", name="*")
+               public Reader echoMethod(@Method String method) {
+                       return new StringReader(method);
+               }
        }
 
+
        private static final Calendar CALENDAR = new 
GregorianCalendar(TimeZone.getTimeZone("Z"));
        static {
                CALENDAR.set(2000, 11, 31, 12, 34, 56);
@@ -146,6 +176,142 @@ public class RestClientTest {
        }
 
        
//------------------------------------------------------------------------------------------------------------------
+       // Closing
+       
//------------------------------------------------------------------------------------------------------------------
+
+       @Test
+       public void a03_close_basic() throws IOException {
+               RestClient.create().build().close();
+               RestClient.create().build().closeQuietly();
+               RestClient.create().keepHttpClientOpen().build().close();
+               RestClient.create().keepHttpClientOpen().build().closeQuietly();
+               RestClient.create().set(RESTCLIENT_httpClient, 
null).keepHttpClientOpen().build().close();
+
+               ExecutorService es = new ThreadPoolExecutor(1, 1, 30, 
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
+               RestClient.create().executorService(es, true).build().close();
+               RestClient.create().executorService(es, 
true).build().closeQuietly();
+               RestClient.create().executorService(es, false).build().close();
+               RestClient.create().executorService(es, 
false).build().closeQuietly();
+
+               RestClient.create().debug().build().close();
+               RestClient.create().debug().build().closeQuietly();
+       }
+
+       @Test
+       public void a04_basicCalls() throws Exception {
+               RestClient rc = MockRestClient
+                       .create(A.class)
+                       .build();
+               rc.get().run().assertBody().is("GET");
+               rc.get("/").run().assertBody().is("GET");
+               rc.get("").run().assertBody().is("GET");
+               rc.put("/", null).run().assertBody().is("PUT");
+               rc.post("/", null).run().assertBody().is("POST");
+               rc.delete("/").run().assertBody().is("DELETE");
+               rc.formPost("/").run().assertBody().is("POST");
+       }
+
+       @Test
+       public void a05_basicCalls_get() throws Exception {
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .build()
+                       .get("/bean")
+                       .run()
+                       .assertBody().is("{f:1}");
+       }
+
+       @Test
+       public void a06_basicCalls_put() throws Exception {
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .build()
+                       .put("/bean", bean)
+                       .run()
+                       .assertBody().is("{f:1}");
+
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .build()
+                       .put("/bean", "{f:1}", "application/json")
+                       .run()
+                       .assertBody().is("{f:1}");
+
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .build()
+                       .put("/bean")
+                       .body(bean)
+                       .run()
+                       .assertBody().is("{f:1}");
+       }
+
+       @Test
+       public void a07_basicCalls_post() throws Exception {
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .build()
+                       .post("/bean", bean)
+                       .run()
+                       .assertBody().is("{f:1}");
+
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .build()
+                       .post("/bean", "{f:1}", "application/json")
+                       .run()
+                       .assertBody().is("{f:1}");
+
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .build()
+                       .post("/bean")
+                       .body(bean)
+                       .run()
+                       .assertBody().is("{f:1}");
+       }
+
+       @Test
+       public void a08_basicCalls_delete() throws Exception {
+               MockRestClient
+               .create(A.class)
+               .simpleJson()
+               .build()
+               .delete("/bean")
+               .run()
+               .assertBody().is("{f:1}");
+       }
+
+       @Test
+       public void a09_basicCalls_options() throws Exception {
+               MockRestClient
+               .create(A.class)
+               .simpleJson()
+               .build()
+               .options("/bean")
+               .run()
+               .assertBody().is("{f:1}");
+       }
+
+       @Test
+       public void a10_basicCalls_head() throws Exception {
+               MockRestClient
+               .create(A.class)
+               .simpleJson()
+               .build()
+               .head("/bean")
+               .run()
+               .assertBody().is("");
+       }
+
+       
//------------------------------------------------------------------------------------------------------------------
        // Logging
        
//------------------------------------------------------------------------------------------------------------------
        @Test
@@ -2394,6 +2560,50 @@ public class RestClientTest {
        }
 
        @Test
+       public void k14a_restClient_invalidSerializersAndParsers() throws 
Exception {
+               try {
+                       MockRestClient
+                               .create(A.class)
+                               .prependTo(RESTCLIENT_serializers, String.class)
+                               .build();
+                       fail();
+               } catch (ContextRuntimeException e) {
+                       assertEquals("RESTCLIENT_serializers property had 
invalid class of type 'java.lang.String'", 
e.getCause(ConfigException.class).getMessage());
+               }
+
+               try {
+                       MockRestClient
+                               .create(A.class)
+                               .prependTo(RESTCLIENT_serializers, "")
+                               .build();
+                       fail();
+               } catch (ContextRuntimeException e) {
+                       assertEquals("RESTCLIENT_serializers property had 
invalid object of type 'java.lang.String'", 
e.getCause(ConfigException.class).getMessage());
+               }
+
+               try {
+                       MockRestClient
+                               .create(A.class)
+                               .prependTo(RESTCLIENT_parsers, String.class)
+                               .build();
+                       fail();
+               } catch (ContextRuntimeException e) {
+                       assertEquals("RESTCLIENT_parsers property had invalid 
class of type 'java.lang.String'", 
e.getCause(ConfigException.class).getMessage());
+               }
+
+               try {
+                       MockRestClient
+                               .create(A.class)
+                               .prependTo(RESTCLIENT_parsers, "")
+                               .build();
+                       fail();
+               } catch (ContextRuntimeException e) {
+                       assertEquals("RESTCLIENT_parsers property had invalid 
object of type 'java.lang.String'", 
e.getCause(ConfigException.class).getMessage());
+               }
+       }
+
+
+       @Test
        public void k15_restClient_serializersClasses_parsersClasses() throws 
Exception {
                @SuppressWarnings("unchecked")
                RestClient rc = MockRestClient
@@ -2520,6 +2730,13 @@ public class RestClientTest {
                        .assertHeader("Foo").is("x{f:1}")
                        .getHeader("Foo").as(Bean.class);
                assertEquals("{f:1}", b.toString());
+               b = rc
+                       .get()
+                       .header("Foo",bean)
+                       .run()
+                       .assertHeader("Foo").is("x{f:1}")
+                       .getHeader("Foo").as(Bean.class);
+               assertEquals("{f:1}", b.toString());
        }
 
        @Test
@@ -3382,6 +3599,21 @@ public class RestClientTest {
                }
        }
 
+       public static class O05a {}
+
+       @Test
+       public void o05a_beanContext_beansDontRequireSomeProperties() throws 
Exception {
+               MockRestClient
+                       .create(A.class)
+                       .beansDontRequireSomeProperties()
+                       .simpleJson()
+                       .build()
+                       .post("/echoBody", new O05a())
+                       .run()
+                       .assertBody().is("{}")
+               ;
+       }
+
        @Test
        public void o06_beanContext_beansRequireDefaultConstructor() throws 
Exception {
                MockRestClient
@@ -4572,6 +4804,21 @@ public class RestClientTest {
                        .getBody().as(O35.class)
                ;
                assertEquals(1, x.foo);
+
+               x = MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .typeName(O35.class, "foo")
+                       .typePropertyName(O35.class, "X")
+                       .addRootType()
+                       .build()
+                       .post("/echoBody", new O35().init())
+                       .run()
+                       .cacheBody()
+                       .assertBody().is("{X:'foo',foo:1}")
+                       .getBody().as(O35.class)
+               ;
+               assertEquals(1, x.foo);
        }
 
        public static enum O37e {
@@ -4613,6 +4860,41 @@ public class RestClientTest {
                assertEquals(O37e.ONE, x.foo);
        }
 
+       public static class O38 {
+               private int foo;
+               public int bar;
+
+               public int getFoo() {
+                       return foo;
+               }
+
+               public void setFoo(int foo) {
+                       this.foo = foo;
+               }
+
+               public O38 init() {
+                       this.foo = 1;
+                       this.bar = 2;
+                       return this;
+               }
+       }
+
+       @Test
+       public void o38_beanContext_useJavaIntrospector() throws Exception {
+               O38 x = MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .useJavaBeanIntrospector()
+                       .build()
+                       .post("/echoBody", new O38().init())
+                       .run()
+                       .cacheBody()
+                       .assertBody().is("{foo:1}")
+                       .getBody().as(O38.class)
+               ;
+               assertEquals(1, x.foo);
+       }
+
        
//-----------------------------------------------------------------------------------------------------------------
        // Context properties
        
//-----------------------------------------------------------------------------------------------------------------
@@ -4847,4 +5129,60 @@ public class RestClientTest {
                        .assertBody().is("{bar:2,baz:3,foo:1}")
                        .getBody().as(P7.class);
        }
+
+       public static interface P14i {
+               void setFoo(int foo);
+               int getFoo();
+       }
+
+       public static class P14 implements P14i {
+               private int foo;
+               @Override
+               public int getFoo() {
+                       return foo;
+               }
+               @Override
+               public void setFoo(int foo) {
+                       this.foo = foo;
+               }
+       }
+
+       @Test
+       public void p14_context_putAllTo() throws Exception {
+               P14i x = MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .putAllTo(BeanContext.BEAN_implClasses, 
AMap.of(P14i.class.getName(), P14.class))
+                       .build()
+                       .post("/echoBody", new StringReader("{foo:1}"))
+                       .run()
+                       .getBody().as(P14i.class)
+               ;
+               assertEquals(1, x.getFoo());
+               assertTrue(x instanceof P14);
+       }
+
+
+       public static class P15 {
+               public int foo = 1;
+       }
+
+       @Test
+       public void p15_context_set() throws Exception {
+               MockRestClient
+                       .create(null)
+                       .set(
+                               AMap.of(
+                                       JsonSerializer.JSON_simpleMode, true,
+                                       WriterSerializer.WSERIALIZER_quoteChar, 
"'",
+                                       MockRestClient.MOCKRESTCLIENT_restBean, 
A.class
+                               )
+                       )
+                       .json()
+                       .build()
+                       .post("/echoBody", new P15())
+                       .run()
+                       .assertBody().is("{foo:1}")
+               ;
+       }
 }
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 c24535a..f178406 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
@@ -244,15 +244,8 @@ public final class RestCallException extends HttpException 
{
         * @param c The throwable type.
         * @return The cause of the specified type, or <jk>null</jk> of not 
found.
         */
-       @SuppressWarnings("unchecked")
        public <T extends Throwable> T getCause(Class<T> c) {
-               Throwable t = this;
-               do {
-                       if (c.isInstance(t))
-                               return (T)t;
-                       t = t.getCause();
-               } while (t != null);
-               return null;
+               return ThrowableUtils.getCause(c, this);
        }
 
        
//------------------------------------------------------------------------------------------------------------------
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 4f9eca9..3cb1727 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
@@ -174,7 +174,7 @@ import org.apache.http.client.CookieStore;
  *             <li class='jm'>{@link RestClient#formPost(Object) 
formPost(Object url)}
  *             <li class='jm'>{@link 
RestClient#formPost(Object,NameValuePairs) formPost(Object url, NameValuePairs 
parameters)}
  *             <li class='jm'>{@link 
RestClient#formPost(Object,NameValuePair...) formPost(Object url, 
NameValuePair...parameters)}
- *             <li class='jm'>{@link RestClient#formPost(Object,Object...) 
formPost(Object url, Object...parameters)}
+ *             <li class='jm'>{@link 
RestClient#formPostPairs(Object,Object...) formPost(Object url, 
Object...parameters)}
  *             <li class='jm'>{@link 
RestClient#request(HttpMethod,Object,Object) request(HttpMethod method, Object 
url, Object body)}
  *     </ul>
  * </ul>
@@ -1921,7 +1921,12 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                        if (o instanceof Serializer) {
                                sgb.append((Serializer)o);  // Don't apply 
PropertyStore.
                        } else if (o instanceof Class) {
+                               Class<?> c = (Class<?>)o;
+                               if (! Serializer.class.isAssignableFrom(c))
+                                       throw new 
ConfigException("RESTCLIENT_serializers property had invalid class of type 
''{0}''", c.getName());
                                
sgb.append(ContextCache.INSTANCE.create((Class<? extends Serializer>)o, ps));
+                       } else {
+                               throw new 
ConfigException("RESTCLIENT_serializers property had invalid object of type 
''{0}''", o.getClass().getName());
                        }
                }
                this.serializers = sgb.build();
@@ -1931,7 +1936,12 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                        if (o instanceof Parser) {
                                pgb.append((Parser)o);  // Don't apply 
PropertyStore.
                        } else if (o instanceof Class) {
+                               Class<?> c = (Class<?>)o;
+                               if (! Parser.class.isAssignableFrom(c))
+                                       throw new 
ConfigException("RESTCLIENT_parsers property had invalid class of type 
''{0}''", c.getName());
                                
pgb.append(ContextCache.INSTANCE.create((Class<? extends Parser>)o, ps));
+                       } else {
+                               throw new ConfigException("RESTCLIENT_parsers 
property had invalid object of type ''{0}''", o.getClass().getName());
                        }
                }
                this.parsers = pgb.build();
@@ -1996,7 +2006,7 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
        @Override
        public void close() throws IOException {
                isClosed = true;
-               if (httpClient != null && ! keepHttpClientOpen)
+               if (! keepHttpClientOpen)
                        httpClient.close();
                if (executorService != null && executorServiceShutdownOnClose)
                        executorService.shutdown();
@@ -2010,7 +2020,7 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
        public void closeQuietly() {
                isClosed = true;
                try {
-                       if (httpClient != null && ! keepHttpClientOpen)
+                       if (! keepHttpClientOpen)
                                httpClient.close();
                        if (executorService != null && 
executorServiceShutdownOnClose)
                                executorService.shutdown();
@@ -2509,7 +2519,7 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
         *      as a parsed object.
         * @throws RestCallException If any authentication errors occurred.
         */
-       public RestRequest formPost(Object url, Object...parameters) throws 
RestCallException {
+       public RestRequest formPostPairs(Object url, Object...parameters) 
throws RestCallException {
                return formPost(url, new NameValuePairs(parameters));
        }
 
diff --git 
a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock2/MockRestClient.java
 
b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock2/MockRestClient.java
index c9fd966..829f521 100644
--- 
a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock2/MockRestClient.java
+++ 
b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock2/MockRestClient.java
@@ -217,7 +217,8 @@ public class MockRestClient extends RestClient implements 
HttpClientConnection {
 
        private static final String PREFIX = "RestClient.";
 
-       static final String
+       @SuppressWarnings("javadoc")
+       public static final String
                MOCKRESTCLIENT_restBean = PREFIX + "restBean.o",
                MOCKRESTCLIENT_restBeanCtx = PREFIX + "restBeanCtx.o",
                MOCKRESTCLIENT_servletPath = PREFIX + "servletPath.s",
@@ -450,8 +451,8 @@ public class MockRestClient extends RestClient implements 
HttpClientConnection {
        }
 
        @Override /* RestClient */
-       public MockRestRequest formPost(Object url, Object...parameters) throws 
RestCallException {
-               return (MockRestRequest)super.formPost(url, parameters);
+       public MockRestRequest formPostPairs(Object url, Object...parameters) 
throws RestCallException {
+               return (MockRestRequest)super.formPostPairs(url, parameters);
        }
 
        @Override /* RestClient */
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/HttpRuntimeException.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/HttpRuntimeException.java
index a2c7c13..d5cdbfd 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/HttpRuntimeException.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/HttpRuntimeException.java
@@ -22,7 +22,7 @@ import org.apache.juneau.reflect.*;
 /**
  * A {@link RuntimeException} meant to wrap a non-{@link RuntimeException}.
  */
-public final class HttpRuntimeException extends RuntimeException {
+public final class HttpRuntimeException extends BasicRuntimeException {
        private static final long serialVersionUID = 1L;
 
        final Throwable t;
@@ -33,6 +33,7 @@ public final class HttpRuntimeException extends 
RuntimeException {
         * @param t Wrapped exception.
         */
        public HttpRuntimeException(Throwable t) {
+               super(t, t == null ? "" : t.getMessage());
                this.t = t;
        }
 
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index 312c02c..5c1780d 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -3969,7 +3969,7 @@ public final class RestContext extends BeanContext {
                                                        addToRouter(routers, 
httpMethod, sm);
                                                }
                                        } catch (Throwable e) {
-                                               throw new 
RestServletException("Problem occurred trying to serialize methods on class 
{0}, methods={1}", rci.inner().getName(), 
SimpleJsonSerializer.DEFAULT.serialize(methodsFound)).initCause(e);
+                                               throw new 
RestServletException(e, "Problem occurred trying to initialize methods on class 
{0}, methods={1}", rci.inner().getName(), 
SimpleJsonSerializer.DEFAULT.serialize(methodsFound));
                                        }
                                }
                        }
@@ -5244,7 +5244,7 @@ public final class RestContext extends BeanContext {
                        } else if (mpi.hasAnnotation(HasQuery.class)) {
                                rp[i] = new 
RestParamDefaults.HasQueryObject(mpi);
                        } else if 
(mpi.hasAnnotation(org.apache.juneau.rest.annotation.Method.class)) {
-                               rp[i] = new RestParamDefaults.MethodObject(mi, 
t);
+                               rp[i] = new RestParamDefaults.MethodObject(mi, 
t, mpi);
                        }
 
                        if (rp[i] == null && ! isPreOrPost)
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
index 7337ebe..df95999 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
@@ -237,8 +237,7 @@ public class RestContextBuilder extends BeanContextBuilder 
implements ServletCon
                        try {
                                m.invoke(resource, args);
                        } catch (Exception e) {
-                               e.printStackTrace();
-                               throw new RestServletException("Exception 
thrown from @RestHook(INIT) method {0}.{0}.", 
m.getDeclaringClass().getSimpleName(), m.getSignature()).initCause(e);
+                               throw new RestServletException(e, "Exception 
thrown from @RestHook(INIT) method {0}.{0}.", 
m.getDeclaringClass().getSimpleName(), m.getSignature());
                        }
                }
                return this;
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContextBuilder.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContextBuilder.java
index a97af30..859897c 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContextBuilder.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContextBuilder.java
@@ -64,7 +64,7 @@ public class RestMethodContextBuilder extends 
BeanContextBuilder {
                } catch (RestServletException e) {
                        throw e;
                } catch (Exception e) {
-                       throw new RestServletException("Exception occurred 
while initializing method ''{0}''", sig).initCause(e);
+                       throw new RestServletException(e, "Exception occurred 
while initializing method ''{0}''", sig);
                }
        }
 
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
index cbd8d5b..027ae17 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
@@ -421,8 +421,8 @@ class RestParamDefaults {
 
        static final class MethodObject extends RestMethodParam {
 
-               protected MethodObject(MethodInfo m, ClassInfo t) throws 
ServletException {
-                       super(OTHER, (ParamInfo)null);
+               protected MethodObject(MethodInfo m, ClassInfo t, ParamInfo 
mpi) throws ServletException {
+                       super(OTHER, mpi);
                        if (! t.is(String.class))
                                throw new RestServletException("Use of @Method 
annotation on parameter that is not a String on method ''{0}''", m.inner());
                }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServletException.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServletException.java
index 7e9735d..b6bdec7 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServletException.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServletException.java
@@ -18,6 +18,8 @@ import java.text.*;
 
 import javax.servlet.*;
 
+import org.apache.juneau.internal.*;
+
 /**
  * General exception thrown from {@link RestServlet} during construction or 
initialization.
  */
@@ -36,14 +38,24 @@ public class RestServletException extends ServletException {
        }
 
        /**
-        * Sets the inner cause for this exception.
+        * Constructor.
+        * 
+        * @param cause The cause. 
+        * @param message The detailed message.
+        * @param args Optional {@link MessageFormat}-style arguments.
+        */
+       public RestServletException(Throwable cause, String message, 
Object...args) {
+               super(format(message, args), cause);
+       }
+
+       /**
+        * Similar to {@link #getCause()} but searches until it finds the 
throwable of the specified type.
         *
-        * @param cause The inner cause.
-        * @return This object (for method chaining).
+        * @param <T> The throwable type.
+        * @param c The throwable type.
+        * @return The cause of the specified type, or <jk>null</jk> of not 
found.
         */
-       @Override /* Throwable */
-       public synchronized RestServletException initCause(Throwable cause) {
-               super.initCause(cause);
-               return this;
+       public <T extends Throwable> T getCause(Class<T> c) {
+               return ThrowableUtils.getCause(c, this);
        }
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/SwaggerGenerator.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/SwaggerGenerator.java
index a91066a..ec6cc14 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/SwaggerGenerator.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/SwaggerGenerator.java
@@ -598,7 +598,7 @@ final class SwaggerGenerator {
 //                     System.err.println(swaggerJson);
                        return jp.parse(swaggerJson, Swagger.class);
                } catch (Exception e) {
-                       throw new RestServletException("Error detected in 
swagger.").initCause(e);
+                       throw new RestServletException(e, "Error detected in 
swagger.");
                }
        }
 

Reply via email to