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 06f3624  Context API refactoring.
06f3624 is described below

commit 06f362499fbbced0695aafbb285fc4c393dcd2ac
Author: JamesBognar <[email protected]>
AuthorDate: Fri Oct 15 13:39:21 2021 -0400

    Context API refactoring.
---
 .../juneau/config/store/ConfigClasspathStore.java  |  4 +-
 .../juneau/config/store/ConfigFileStore.java       |  4 +-
 .../juneau/config/store/ConfigMemoryStore.java     |  4 +-
 .../java/org/apache/juneau/jena/RdfParser.java     | 20 ++++++++-
 .../java/org/apache/juneau/jena/RdfSerializer.java | 25 ++++++++++-
 .../main/java/org/apache/juneau/BeanContext.java   | 11 ++---
 .../java/org/apache/juneau/BeanContextable.java    | 12 +++++-
 .../org/apache/juneau/BeanTraverseContext.java     | 14 ++++++-
 .../src/main/java/org/apache/juneau/Context.java   | 49 +++++++++++-----------
 .../main/java/org/apache/juneau/csv/CsvParser.java | 10 ++++-
 .../java/org/apache/juneau/csv/CsvSerializer.java  | 10 ++++-
 .../org/apache/juneau/html/HtmlDocSerializer.java  | 26 +++++++++++-
 .../java/org/apache/juneau/html/HtmlParser.java    | 10 ++++-
 .../apache/juneau/html/HtmlSchemaSerializer.java   | 13 +++++-
 .../org/apache/juneau/html/HtmlSerializer.java     | 18 +++++++-
 .../juneau/html/HtmlStrippedDocSerializer.java     | 10 ++++-
 .../org/apache/juneau/internal/ClassUtils.java     |  2 +-
 .../main/java/org/apache/juneau/jso/JsoParser.java | 10 ++++-
 .../java/org/apache/juneau/jso/JsoSerializer.java  | 10 ++++-
 .../java/org/apache/juneau/json/JsonParser.java    | 13 +++++-
 .../apache/juneau/json/JsonSchemaSerializer.java   | 13 +++++-
 .../org/apache/juneau/json/JsonSerializer.java     | 15 ++++++-
 .../juneau/jsonschema/JsonSchemaGenerator.java     | 21 +++++++++-
 .../org/apache/juneau/msgpack/MsgPackParser.java   |  9 +++-
 .../apache/juneau/msgpack/MsgPackSerializer.java   | 13 +++++-
 .../java/org/apache/juneau/oapi/OpenApiParser.java | 14 ++++++-
 .../org/apache/juneau/oapi/OpenApiSerializer.java  | 14 ++++++-
 .../apache/juneau/parser/InputStreamParser.java    | 11 ++++-
 .../main/java/org/apache/juneau/parser/Parser.java | 16 ++++++-
 .../org/apache/juneau/parser/ReaderParser.java     | 12 +++++-
 .../apache/juneau/plaintext/PlainTextParser.java   | 10 ++++-
 .../juneau/plaintext/PlainTextSerializer.java      | 10 ++++-
 .../java/org/apache/juneau/reflect/ClassInfo.java  |  2 +-
 .../org/apache/juneau/reflect/ConstructorInfo.java | 19 +++++++--
 .../juneau/serializer/OutputStreamSerializer.java  | 11 ++++-
 .../org/apache/juneau/serializer/Serializer.java   | 24 ++++++++++-
 .../apache/juneau/serializer/WriterSerializer.java | 16 ++++++-
 .../org/apache/juneau/soap/SoapXmlSerializer.java  | 13 +++++-
 .../main/java/org/apache/juneau/uon/UonParser.java | 14 ++++++-
 .../java/org/apache/juneau/uon/UonSerializer.java  | 16 ++++++-
 .../juneau/urlencoding/UrlEncodingParser.java      | 13 +++++-
 .../juneau/urlencoding/UrlEncodingSerializer.java  | 13 +++++-
 .../main/java/org/apache/juneau/xml/XmlParser.java | 17 +++++++-
 .../java/org/apache/juneau/xml/XmlSerializer.java  | 18 +++++++-
 .../rest/test/client/ThirdPartyProxyTest.java      |  5 +++
 .../org/apache/juneau/rest/client/RestClient.java  |  5 +--
 .../java/org/apache/juneau/rest/RestContext.java   |  2 +-
 .../juneau/reflection/ConstructorInfoTest.java     | 10 ++---
 .../juneau/rest/annotation/Rest_Context_Test.java  |  2 +-
 .../apache/juneau/testutils/MockReaderParser.java  |  5 +++
 .../apache/juneau/testutils/MockStreamParser.java  |  5 +++
 .../juneau/testutils/MockStreamSerializer.java     |  5 +++
 .../juneau/testutils/MockWriterSerializer.java     |  5 +++
 53 files changed, 562 insertions(+), 91 deletions(-)

diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
index a289353..525b2ff 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
@@ -64,6 +64,7 @@ public class ConfigClasspathStore extends ConfigStore {
                 */
                protected Builder() {
                        super();
+                       type(ConfigClasspathStore.class);
                }
 
                /**
@@ -73,6 +74,7 @@ public class ConfigClasspathStore extends ConfigStore {
                 */
                protected Builder(ConfigClasspathStore copyFrom) {
                        super(copyFrom);
+                       type(copyFrom.getClass());
                }
 
                /**
@@ -91,7 +93,7 @@ public class ConfigClasspathStore extends ConfigStore {
 
                @Override /* Context.Builder */
                public ConfigClasspathStore build() {
-                       return new ConfigClasspathStore(this);
+                       return build(ConfigClasspathStore.class, null);
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStore.java
 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStore.java
index c4b11bc..2460f23 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStore.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStore.java
@@ -76,6 +76,7 @@ public class ConfigFileStore extends ConfigStore {
                 */
                protected Builder() {
                        super();
+                       type(ConfigFileStore.class);
                        directory = env("ConfigFileStore.directory", ".");
                        charset = env("ConfigFileStore.charset", 
Charset.defaultCharset());
                        enableWatcher = env("ConfigFileStore.enableWatcher", 
false);
@@ -91,6 +92,7 @@ public class ConfigFileStore extends ConfigStore {
                 */
                protected Builder(ConfigFileStore copyFrom) {
                        super(copyFrom);
+                       type(copyFrom.getClass());
                        directory = copyFrom.directory;
                        charset = copyFrom.charset;
                        enableWatcher = copyFrom.enableWatcher;
@@ -121,7 +123,7 @@ public class ConfigFileStore extends ConfigStore {
 
                @Override /* Context.Builder */
                public ConfigFileStore build() {
-                       return new ConfigFileStore(this);
+                       return build(ConfigFileStore.class, null);
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStore.java
 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStore.java
index 4d00a1a..d5df9de 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStore.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStore.java
@@ -61,6 +61,7 @@ public class ConfigMemoryStore extends ConfigStore {
                 */
                protected Builder() {
                        super();
+                       type(ConfigMemoryStore.class);
                }
 
                /**
@@ -70,6 +71,7 @@ public class ConfigMemoryStore extends ConfigStore {
                 */
                protected Builder(ConfigMemoryStore copyFrom) {
                        super(copyFrom);
+                       type(copyFrom.getClass());
                }
 
                /**
@@ -88,7 +90,7 @@ public class ConfigMemoryStore extends ConfigStore {
 
                @Override /* Context.Builder */
                public ConfigMemoryStore build() {
-                       return new ConfigMemoryStore(this);
+                       return build(ConfigMemoryStore.class, null);
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
index 374eca9..6a5f78e 100644
--- 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
@@ -24,10 +24,12 @@ import java.util.concurrent.*;
 import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.MediaType;
+import org.apache.juneau.internal.Cache;
 import org.apache.juneau.internal.FluentSetter;
 import org.apache.juneau.internal.FluentSetters;
 import org.apache.juneau.jena.annotation.Rdf;
 import org.apache.juneau.parser.*;
+import org.apache.juneau.utils.HashKey;
 import org.apache.juneau.xml.*;
 
 /**
@@ -77,6 +79,8 @@ public class RdfParser extends ReaderParser implements 
RdfMetaProvider {
        @FluentSetters
        public static class Builder extends ReaderParser.Builder {
 
+               private static final Cache<HashKey,RdfParser> CACHE = 
Cache.of(HashKey.class, RdfParser.class).build();
+
                private static final Namespace
                        DEFAULT_JUNEAU_NS = Namespace.of("j", 
"http://www.apache.org/juneau/";),
                        DEFAULT_JUNEAUBP_NS = Namespace.of("jp", 
"http://www.apache.org/juneaubp/";);
@@ -141,7 +145,21 @@ public class RdfParser extends ReaderParser implements 
RdfMetaProvider {
 
                @Override /* Context.Builder */
                public RdfParser build() {
-                       return (RdfParser)super.build();
+                       return build(RdfParser.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               trimWhitespace,
+                               looseCollections,
+                               language,
+                               collectionFormat,
+                               juneauNs,
+                               juneauBpNs,
+                               jenaSettings
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
index 10fb5fe..5ca46ec 100644
--- 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
@@ -25,10 +25,12 @@ import java.util.concurrent.*;
 import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.MediaType;
+import org.apache.juneau.internal.Cache;
 import org.apache.juneau.internal.FluentSetter;
 import org.apache.juneau.internal.FluentSetters;
 import org.apache.juneau.jena.annotation.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.utils.HashKey;
 import org.apache.juneau.xml.*;
 import org.apache.juneau.xml.annotation.*;
 
@@ -76,6 +78,8 @@ public class RdfSerializer extends WriterSerializer 
implements RdfMetaProvider {
        @FluentSetters
        public static class Builder extends WriterSerializer.Builder {
 
+               private static final Cache<HashKey,RdfSerializer> CACHE = 
Cache.of(HashKey.class, RdfSerializer.class).build();
+
                private static final Namespace
                        DEFAULT_JUNEAU_NS = Namespace.of("j", 
"http://www.apache.org/juneau/";),
                        DEFAULT_JUNEAUBP_NS = Namespace.of("jp", 
"http://www.apache.org/juneaubp/";);
@@ -156,7 +160,26 @@ public class RdfSerializer extends WriterSerializer 
implements RdfMetaProvider {
 
                @Override /* Context.Builder */
                public RdfSerializer build() {
-                       return (RdfSerializer)super.build();
+                       return build(RdfSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               addBeanTypesRdf,
+                               addLiteralTypes,
+                               addRootProperty,
+                               disableAutoDetectNamespaces,
+                               disableUseXmlNamespaces,
+                               looseCollections,
+                               language,
+                               collectionFormat,
+                               juneauNs,
+                               juneauBpNs,
+                               namespaces,
+                               jenaSettings
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
index 75913f6..e9116a9 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
@@ -243,6 +243,7 @@ public class BeanContext extends Context {
                 */
                protected Builder() {
                        super();
+                       type(BeanContext.class);
                        beanClassVisibility = 
env("BeanContext.beanClassVisibility", PUBLIC);
                        beanConstructorVisibility = 
env("BeanContext.beanConstructorVisibility", PUBLIC);
                        beanMethodVisibility = 
env("BeanContext.beanMethodVisibility", PUBLIC);
@@ -357,13 +358,10 @@ public class BeanContext extends Context {
 
                @Override /* Context.Builder */
                public BeanContext build() {
-                       BeanContext impl = impl(BeanContext.class);
-                       if (impl != null)
-                               return impl;
-                       return CACHE.get(hashKey(), ()->new BeanContext(this));
+                       return build(BeanContext.class, CACHE);
                }
 
-               @Override
+               @Override /* Context.Builder */
                public HashKey hashKey() {
                        return HashKey.of(
                                super.hashKey(),
@@ -3467,6 +3465,7 @@ public class BeanContext extends Context {
        final Class<? extends PropertyNamer> propertyNamer;
        final List<Class<?>> beanDictionary, swaps, notBeanClasses;
        final List<String> notBeanPackages;
+       final HashKey hashKey;
 
        final Map<Class,ClassMeta> cmCache;
 
@@ -3490,6 +3489,8 @@ public class BeanContext extends Context {
        protected BeanContext(Builder builder) {
                super(builder);
 
+               hashKey = builder.hashKey();
+
                beanConstructorVisibility = builder.beanConstructorVisibility;
                beanClassVisibility = builder.beanClassVisibility;
                beanMethodVisibility = builder.beanMethodVisibility;
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContextable.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContextable.java
index 0d7f61b..17ba0cb 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContextable.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContextable.java
@@ -27,6 +27,7 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.transform.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Context class for classes that use {@link BeanContext} objects.
@@ -84,8 +85,15 @@ public abstract class BeanContextable extends Context {
                public abstract Builder copy();
 
                @Override /* Context.Builder */
-               public BeanContextable build() {
-                       return (BeanContextable)super.build();
+               public abstract BeanContextable build();
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               bcBuilder.hashKey(),
+                               bc == null ? 0 : bc.hashKey
+                       );
                }
 
                /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseContext.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseContext.java
index 6b3d2a3..65782eb 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseContext.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseContext.java
@@ -23,6 +23,7 @@ import java.util.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Parent class for all classes that traverse POJOs.
@@ -88,8 +89,17 @@ public abstract class BeanTraverseContext extends 
BeanContextable {
                public abstract Builder copy();
 
                @Override /* Context.Builder */
-               public BeanTraverseContext build() {
-                       return (BeanTraverseContext)super.build();
+               public abstract BeanTraverseContext build();
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               detectRecursions,
+                               ignoreRecursions,
+                               initialDepth,
+                               maxDepth
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
index e66cdf7..61dddc5 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
@@ -168,25 +168,7 @@ public abstract class Context implements MetaProvider {
                 *
                 * @return The built object.
                 */
-               public Context build() {
-                       if (impl != null)
-                               return impl;
-                       if (type == null)
-                               throw runtimeException("Context class not 
specified.");
-                       ConstructorInfo cci = CONTEXT_CONSTRUCTORS.get(type);
-                       if (cci == null) {
-                               ClassInfo ci = ClassInfo.of(type);
-                               cci = 
ci.getConstructor(isVisible(PROTECTED).and(hasParentArgs(this))).map(x -> 
x.accessible()).orElse(null);
-                               if (cci == null)
-                                       throw runtimeException("Constructor not 
found for class {0}", type);
-                               CONTEXT_CONSTRUCTORS.put(type, cci);
-                       }
-                       try {
-                               return cci.invoke(this);
-                       } catch (ExecutableException e) {
-                               throw runtimeException(e, "Error occurred 
trying to create context.");
-                       }
-               }
+               public abstract Context build();
 
                /**
                 * Returns the hashkey of this builder.
@@ -203,15 +185,34 @@ public abstract class Context implements MetaProvider {
                }
 
                /**
-                * Returns the {@link #impl(Context)} bean if it's the 
specified type.
+                * Builds the context from this builder.
                 *
-                * @param c The expected bean type.
-                * @return The impl bean, or <jk>null</jk> if an impl bean 
wasn't specified.
+                * <p>
+                * Looks for a public/protected constructor that takes in this 
builder bean.
+                * If <c>cache</c> is specified, then the created bean will be 
cached using {@link #hashKey()} as the key.
+                *
+                * @param c The context class being created.
+                * @param cache Optional cache to use for caching and 
retrieving existing instances.
+                * @return A new context object.
                 */
-               protected <T extends Context> T impl(Class<T> c) {
+               protected <T extends Context> T build(Class<T> c, 
Cache<HashKey,T> cache) {
                        if (impl != null && c.isInstance(impl))
                                return c.cast(impl);
-                       return null;
+                       if (cache != null)
+                               return cache.get(hashKey(), 
()->getContextConstructor().invoke(this));
+                       return getContextConstructor().invoke(this);
+               }
+
+               private ConstructorInfo getContextConstructor() {
+                       ConstructorInfo cci = CONTEXT_CONSTRUCTORS.get(type);
+                       if (cci == null) {
+                               ClassInfo ci = ClassInfo.of(type);
+                               cci = 
ci.getConstructor(isVisible(PROTECTED).and(hasParentArgs(this))).map(x -> 
x.accessible()).orElse(null);
+                               if (cci == null)
+                                       throw runtimeException("Constructor not 
found for class {0}", type);
+                               CONTEXT_CONSTRUCTORS.put(type, cci);
+                       }
+                       return cci;
                }
 
                private static final Map<Class<?>,ConstructorInfo> 
CONTEXT_CONSTRUCTORS = new ConcurrentHashMap<>();
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParser.java
index 819dce2..85b17e2 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParser.java
@@ -22,6 +22,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
+import org.apache.juneau.utils.*;
 
 /**
  * TODO - Work in progress.  CSV parser.
@@ -54,6 +55,8 @@ public class CsvParser extends ReaderParser implements 
CsvMetaProvider {
        @FluentSetters
        public static class Builder extends ReaderParser.Builder {
 
+               private static final Cache<HashKey,CsvParser> CACHE = 
Cache.of(HashKey.class, CsvParser.class).build();
+
                /**
                 * Constructor, default settings.
                 */
@@ -88,7 +91,12 @@ public class CsvParser extends ReaderParser implements 
CsvMetaProvider {
 
                @Override /* Context.Builder */
                public CsvParser build() {
-                       return (CsvParser)super.build();
+                       return build(CsvParser.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return super.hashKey();
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java
index a241b62..9723fd2 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java
@@ -22,6 +22,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.utils.*;
 
 /**
  * TODO - Work in progress.  CSV serializer.
@@ -54,6 +55,8 @@ public final class CsvSerializer extends WriterSerializer 
implements CsvMetaProv
        @FluentSetters
        public static class Builder extends WriterSerializer.Builder {
 
+               private static final Cache<HashKey,CsvSerializer> CACHE = 
Cache.of(HashKey.class, CsvSerializer.class).build();
+
                /**
                 * Constructor, default settings.
                 */
@@ -88,7 +91,12 @@ public final class CsvSerializer extends WriterSerializer 
implements CsvMetaProv
 
                @Override /* Context.Builder */
                public CsvSerializer build() {
-                       return (CsvSerializer)super.build();
+                       return build(CsvSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return super.hashKey();
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
index 653fd95..19ab983 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
@@ -28,6 +28,7 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.svl.*;
+import org.apache.juneau.utils.*;
 import org.apache.juneau.xml.*;
 
 /**
@@ -98,6 +99,8 @@ public class HtmlDocSerializer extends 
HtmlStrippedDocSerializer {
        @FluentSetters
        public static class Builder extends HtmlStrippedDocSerializer.Builder {
 
+               private static final Cache<HashKey,HtmlDocSerializer> CACHE = 
Cache.of(HashKey.class, HtmlDocSerializer.class).build();
+
                List<String> aside, footer, head, header, nav, navlinks, 
script, style, stylesheet;
                AsideFloat asideFloat;
                String noResultsMessage;
@@ -171,7 +174,28 @@ public class HtmlDocSerializer extends 
HtmlStrippedDocSerializer {
 
                @Override /* Context.Builder */
                public HtmlDocSerializer build() {
-                       return (HtmlDocSerializer)super.build();
+                       return build(HtmlDocSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               aside,
+                               footer,
+                               head,
+                               header,
+                               nav,
+                               navlinks,
+                               script,
+                               style,
+                               stylesheet,
+                               asideFloat,
+                               noResultsMessage,
+                               nowrap,
+                               template,
+                               widgets
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParser.java
index b91ee2d..2051bee 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParser.java
@@ -21,6 +21,7 @@ import java.util.concurrent.*;
 import org.apache.juneau.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
+import org.apache.juneau.utils.*;
 import org.apache.juneau.xml.*;
 
 /**
@@ -64,6 +65,8 @@ public class HtmlParser extends XmlParser implements 
HtmlMetaProvider {
        @FluentSetters
        public static class Builder extends XmlParser.Builder {
 
+               private static final Cache<HashKey,HtmlParser> CACHE = 
Cache.of(HashKey.class, HtmlParser.class).build();
+
                /**
                 * Constructor, default settings.
                 */
@@ -98,7 +101,12 @@ public class HtmlParser extends XmlParser implements 
HtmlMetaProvider {
 
                @Override /* Context.Builder */
                public HtmlParser build() {
-                       return (HtmlParser)super.build();
+                       return build(HtmlParser.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return super.hashKey();
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializer.java
index 94a5929..8a13c0d 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializer.java
@@ -27,6 +27,7 @@ import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.jsonschema.*;
 import org.apache.juneau.jsonschema.annotation.*;
+import org.apache.juneau.utils.*;
 import org.apache.juneau.xml.*;
 
 /**
@@ -129,6 +130,8 @@ public class HtmlSchemaSerializer extends HtmlSerializer {
        @FluentSetters
        public static class Builder extends HtmlSerializer.Builder {
 
+               private static final Cache<HashKey,HtmlSchemaSerializer> CACHE 
= Cache.of(HashKey.class, HtmlSchemaSerializer.class).build();
+
                JsonSchemaGenerator.Builder generatorBuilder;
 
                /**
@@ -169,7 +172,15 @@ public class HtmlSchemaSerializer extends HtmlSerializer {
 
                @Override /* Context.Builder */
                public HtmlSchemaSerializer build() {
-                       return (HtmlSchemaSerializer)super.build();
+                       return build(HtmlSchemaSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               generatorBuilder.hashKey()
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
index 4bf1137..3b4a735 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
@@ -27,6 +27,7 @@ import org.apache.juneau.html.annotation.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.utils.*;
 import org.apache.juneau.xml.*;
 
 /**
@@ -198,6 +199,8 @@ public class HtmlSerializer extends XmlSerializer 
implements HtmlMetaProvider {
        @FluentSetters
        public static class Builder extends XmlSerializer.Builder {
 
+               private static final Cache<HashKey,HtmlSerializer> CACHE = 
Cache.of(HashKey.class, HtmlSerializer.class).build();
+
                boolean addBeanTypesHtml, addKeyValueTableHeaders, 
disableDetectLabelParameters, disableDetectLinksInStrings;
                String labelParameter;
                AnchorText uriAnchorText;
@@ -254,7 +257,20 @@ public class HtmlSerializer extends XmlSerializer 
implements HtmlMetaProvider {
 
                @Override /* Context.Builder */
                public HtmlSerializer build() {
-                       return (HtmlSerializer)super.build();
+                       return build(HtmlSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               addBeanTypesHtml,
+                               addKeyValueTableHeaders,
+                               disableDetectLabelParameters,
+                               disableDetectLinksInStrings,
+                               labelParameter,
+                               uriAnchorText
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
index 5418616..5ecae4a 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
@@ -20,6 +20,7 @@ import java.util.*;
 import org.apache.juneau.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
+import org.apache.juneau.utils.*;
 import org.apache.juneau.xml.*;
 
 /**
@@ -65,6 +66,8 @@ public class HtmlStrippedDocSerializer extends HtmlSerializer 
{
        @FluentSetters
        public static class Builder extends HtmlSerializer.Builder {
 
+               private static final Cache<HashKey,HtmlStrippedDocSerializer> 
CACHE = Cache.of(HashKey.class, HtmlStrippedDocSerializer.class).build();
+
                /**
                 * Constructor, default settings.
                 */
@@ -100,7 +103,12 @@ public class HtmlStrippedDocSerializer extends 
HtmlSerializer {
 
                @Override /* Context.Builder */
                public HtmlStrippedDocSerializer build() {
-                       return (HtmlStrippedDocSerializer)super.build();
+                       return build(HtmlStrippedDocSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return super.hashKey();
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
index fca2850..8021767 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
@@ -149,7 +149,7 @@ public final class ClassUtils {
 
                                        con = 
c3.getPublicConstructorFuzzy(args);
                                        if (con != null)
-                                               return 
con.<T>invoke(getMatchingArgs(con.getParamTypes(), args));
+                                               return con.<T>invokeFuzzy(args);
                                }
 
                                throw runtimeException("Could not instantiate 
class {0}/{1}.  Constructor not found.", className(c), c2);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoParser.java
index cc7d5c5..67fd2e3 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoParser.java
@@ -22,6 +22,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Parses POJOs from HTTP responses as Java {@link ObjectInputStream 
ObjectInputStreams}.
@@ -58,6 +59,8 @@ public final class JsoParser extends InputStreamParser 
implements JsoMetaProvide
        @FluentSetters
        public static class Builder extends InputStreamParser.Builder {
 
+               private static final Cache<HashKey,JsoParser> CACHE = 
Cache.of(HashKey.class, JsoParser.class).build();
+
                /**
                 * Constructor, default settings.
                 */
@@ -92,7 +95,12 @@ public final class JsoParser extends InputStreamParser 
implements JsoMetaProvide
 
                @Override /* Context.Builder */
                public JsoParser build() {
-                       return (JsoParser)super.build();
+                       return build(JsoParser.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return super.hashKey();
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializer.java
index 02ed707..ca670fc 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializer.java
@@ -22,6 +22,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Serializes POJOs to HTTP responses as Java Serialized Object {@link 
ObjectOutputStream ObjectOutputStreams}.
@@ -60,6 +61,8 @@ public class JsoSerializer extends OutputStreamSerializer 
implements JsoMetaProv
        @FluentSetters
        public static class Builder extends OutputStreamSerializer.Builder {
 
+               private static final Cache<HashKey,JsoSerializer> CACHE = 
Cache.of(HashKey.class, JsoSerializer.class).build();
+
                /**
                 * Constructor, default settings.
                 */
@@ -94,7 +97,12 @@ public class JsoSerializer extends OutputStreamSerializer 
implements JsoMetaProv
 
                @Override /* Context.Builder */
                public JsoSerializer build() {
-                       return (JsoSerializer)super.build();
+                       return build(JsoSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return super.hashKey();
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java
index 4b92023..b1280a2 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java
@@ -25,6 +25,7 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Parses any valid JSON text into a POJO model.
@@ -158,6 +159,8 @@ public class JsonParser extends ReaderParser implements 
JsonMetaProvider {
        @FluentSetters
        public static class Builder extends ReaderParser.Builder {
 
+               private static final Cache<HashKey,JsonParser> CACHE = 
Cache.of(HashKey.class, JsonParser.class).build();
+
                boolean validateEnd;
 
                /**
@@ -197,7 +200,15 @@ public class JsonParser extends ReaderParser implements 
JsonMetaProvider {
 
                @Override /* Context.Builder */
                public JsonParser build() {
-                       return (JsonParser)super.build();
+                       return build(JsonParser.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               validateEnd
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java
index 8720077..97863e0 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java
@@ -27,6 +27,7 @@ import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.jsonschema.*;
 import org.apache.juneau.jsonschema.annotation.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Serializes POJO metadata to HTTP responses as JSON-Schema.
@@ -121,6 +122,8 @@ public class JsonSchemaSerializer extends JsonSerializer 
implements JsonSchemaMe
        @FluentSetters
        public static class Builder extends JsonSerializer.Builder {
 
+               private static final Cache<HashKey,JsonSchemaSerializer> CACHE 
= Cache.of(HashKey.class, JsonSchemaSerializer.class).build();
+
                JsonSchemaGenerator.Builder generatorBuilder;
 
                /**
@@ -161,7 +164,15 @@ public class JsonSchemaSerializer extends JsonSerializer 
implements JsonSchemaMe
 
                @Override /* Context.Builder */
                public JsonSchemaSerializer build() {
-                       return (JsonSchemaSerializer)super.build();
+                       return build(JsonSchemaSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               generatorBuilder.hashKey()
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
index d94db8f..0fb7c5e 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
@@ -26,6 +26,7 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Serializes POJO models to JSON.
@@ -161,6 +162,8 @@ public class JsonSerializer extends WriterSerializer 
implements JsonMetaProvider
        @FluentSetters
        public static class Builder extends WriterSerializer.Builder {
 
+               private static final Cache<HashKey,JsonSerializer> CACHE = 
Cache.of(HashKey.class, JsonSerializer.class).build();
+
                boolean addBeanTypesJson, escapeSolidus, simpleMode;
 
                /**
@@ -207,7 +210,17 @@ public class JsonSerializer extends WriterSerializer 
implements JsonMetaProvider
 
                @Override /* Context.Builder */
                public JsonSerializer build() {
-                       return (JsonSerializer)super.build();
+                       return build(JsonSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               addBeanTypesJson,
+                               escapeSolidus,
+                               simpleMode
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGenerator.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGenerator.java
index a0b4079..ee99d51 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGenerator.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGenerator.java
@@ -31,6 +31,7 @@ import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.jsonschema.annotation.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Generates JSON-schema metadata about POJOs.
@@ -64,6 +65,8 @@ public class JsonSchemaGenerator extends BeanTraverseContext 
implements JsonSche
        @FluentSetters
        public static class Builder extends BeanTraverseContext.Builder {
 
+               private static final Cache<HashKey,JsonSchemaGenerator> CACHE = 
Cache.of(HashKey.class, JsonSchemaGenerator.class).build();
+
                final JsonSerializer.Builder jsonSerializerBuilder;
                final JsonParser.Builder jsonParserBuilder;
 
@@ -138,7 +141,23 @@ public class JsonSchemaGenerator extends 
BeanTraverseContext implements JsonSche
 
                @Override /* Context.Builder */
                public JsonSchemaGenerator build() {
-                       return (JsonSchemaGenerator)super.build();
+                       return build(JsonSchemaGenerator.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               jsonSerializerBuilder.hashKey(),
+                               jsonParserBuilder.hashKey(),
+                               addDescriptionsTo,
+                               addExamplesTo,
+                               allowNestedDescriptions,
+                               allowNestedExamples,
+                               useBeanDefs,
+                               beanDefMapper,
+                               ignoreTypes
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
index 3de5c01..e95e58c 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
@@ -21,6 +21,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Parses a MessagePack stream into a POJO model.
@@ -97,6 +98,8 @@ public class MsgPackParser extends InputStreamParser 
implements MsgPackMetaProvi
        @FluentSetters
        public static class Builder extends InputStreamParser.Builder {
 
+               private static final Cache<HashKey,MsgPackParser> CACHE = 
Cache.of(HashKey.class, MsgPackParser.class).build();
+
                /**
                 * Constructor, default settings.
                 */
@@ -131,9 +134,13 @@ public class MsgPackParser extends InputStreamParser 
implements MsgPackMetaProvi
 
                @Override /* Context.Builder */
                public MsgPackParser build() {
-                       return (MsgPackParser)super.build();
+                       return build(MsgPackParser.class, CACHE);
                }
 
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return super.hashKey();
+               }
                
//-----------------------------------------------------------------------------------------------------------------
                // Properties
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
index a796263..2b1bee8 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
@@ -25,6 +25,7 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Serializes POJO models to MessagePack.
@@ -100,6 +101,8 @@ public class MsgPackSerializer extends 
OutputStreamSerializer implements MsgPack
        @FluentSetters
        public static class Builder extends OutputStreamSerializer.Builder {
 
+               private static final Cache<HashKey,MsgPackSerializer> CACHE = 
Cache.of(HashKey.class, MsgPackSerializer.class).build();
+
                boolean addBeanTypesMsgPack;
 
                /**
@@ -137,7 +140,15 @@ public class MsgPackSerializer extends 
OutputStreamSerializer implements MsgPack
 
                @Override /* Context.Builder */
                public MsgPackSerializer build() {
-                       return (MsgPackSerializer)super.build();
+                       return build(MsgPackSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               addBeanTypesMsgPack
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParser.java
index f3ad4a3..c60a051 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParser.java
@@ -24,6 +24,7 @@ import org.apache.juneau.httppart.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.jsonschema.annotation.*;
 import org.apache.juneau.uon.*;
+import org.apache.juneau.utils.*;
 
 /**
  * OpenAPI part parser.
@@ -60,6 +61,8 @@ public class OpenApiParser extends UonParser implements 
OpenApiMetaProvider {
        @FluentSetters
        public static class Builder extends UonParser.Builder {
 
+               private static final Cache<HashKey,OpenApiParser> CACHE = 
Cache.of(HashKey.class, OpenApiParser.class).build();
+
                HttpPartFormat format;
                HttpPartCollectionFormat collectionFormat;
 
@@ -103,7 +106,16 @@ public class OpenApiParser extends UonParser implements 
OpenApiMetaProvider {
 
                @Override /* Context.Builder */
                public OpenApiParser build() {
-                       return (OpenApiParser)super.build();
+                       return build(OpenApiParser.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               format,
+                               collectionFormat
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializer.java
index 9899c6c..93a1b3b 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializer.java
@@ -24,6 +24,7 @@ import org.apache.juneau.httppart.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.jsonschema.annotation.*;
 import org.apache.juneau.uon.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Serializes POJOs to values suitable for transmission as HTTP headers, 
query/form-data parameters, and path variables.
@@ -60,6 +61,8 @@ public class OpenApiSerializer extends UonSerializer 
implements OpenApiMetaProvi
        @FluentSetters
        public static class Builder extends UonSerializer.Builder {
 
+               private static final Cache<HashKey,OpenApiSerializer> CACHE = 
Cache.of(HashKey.class, OpenApiSerializer.class).build();
+
                HttpPartFormat format;
                HttpPartCollectionFormat collectionFormat;
 
@@ -103,7 +106,16 @@ public class OpenApiSerializer extends UonSerializer 
implements OpenApiMetaProvi
 
                @Override /* Context.Builder */
                public OpenApiSerializer build() {
-                       return (OpenApiSerializer)super.build();
+                       return build(OpenApiSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               format,
+                               collectionFormat
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParser.java
index d64fbc7..3f97146 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParser.java
@@ -23,6 +23,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Subclass of {@link Parser} for byte-based parsers.
@@ -82,8 +83,14 @@ public abstract class InputStreamParser extends Parser {
                public abstract Builder copy();
 
                @Override /* Context.Builder */
-               public InputStreamParser build() {
-                       return (InputStreamParser)super.build();
+               public abstract InputStreamParser build();
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               binaryFormat
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
index ac0f370..ed90bb0 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
@@ -218,8 +218,20 @@ public abstract class Parser extends BeanContextable {
                public abstract Builder copy();
 
                @Override /* Context.Builder */
-               public Parser build() {
-                       return (Parser)super.build();
+               public abstract Parser build();
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               autoCloseStreams,
+                               strict,
+                               trimStrings,
+                               unbuffered,
+                               debugOutputLines,
+                               listener,
+                               consumes
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParser.java
index 0934c3b..5ace5fd 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParser.java
@@ -24,6 +24,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Subclass of {@link Parser} for characters-based parsers.
@@ -86,8 +87,15 @@ public abstract class ReaderParser extends Parser {
                public abstract Builder copy();
 
                @Override /* Context.Builder */
-               public ReaderParser build() {
-                       return (ReaderParser)super.build();
+               public abstract ReaderParser build();
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               fileCharset,
+                               streamCharset
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java
index 8d73bbc..bd8a004 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java
@@ -23,6 +23,7 @@ import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.transform.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Parsers HTTP plain text request bodies into Group 5 POJOs.
@@ -73,6 +74,8 @@ public class PlainTextParser extends ReaderParser implements 
PlainTextMetaProvid
        @FluentSetters
        public static class Builder extends ReaderParser.Builder {
 
+               private static final Cache<HashKey,PlainTextParser> CACHE = 
Cache.of(HashKey.class, PlainTextParser.class).build();
+
                /**
                 * Constructor, default settings.
                 */
@@ -107,7 +110,12 @@ public class PlainTextParser extends ReaderParser 
implements PlainTextMetaProvid
 
                @Override /* Context.Builder */
                public PlainTextParser build() {
-                       return (PlainTextParser)super.build();
+                       return build(PlainTextParser.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return super.hashKey();
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
index f145c81..7387469 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
@@ -23,6 +23,7 @@ import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.transform.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Serializes POJOs to plain text using just the <c>toString()</c> method on 
the serialized object.
@@ -69,6 +70,8 @@ public class PlainTextSerializer extends WriterSerializer 
implements PlainTextMe
        @FluentSetters
        public static class Builder extends WriterSerializer.Builder {
 
+               private static final Cache<HashKey,PlainTextSerializer> CACHE = 
Cache.of(HashKey.class, PlainTextSerializer.class).build();
+
                /**
                 * Constructor, default settings.
                 */
@@ -103,7 +106,12 @@ public class PlainTextSerializer extends WriterSerializer 
implements PlainTextMe
 
                @Override /* Context.Builder */
                public PlainTextSerializer build() {
-                       return (PlainTextSerializer)super.build();
+                       return build(PlainTextSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return super.hashKey();
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
index 198ee8d..5835c85 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
@@ -944,7 +944,7 @@ public final class ClassInfo {
                boolean isMemberClass = isNonStaticMemberClass();
                for (ConstructorInfo cc : _getDeclaredConstructors())
                        if (cc.hasNumParams(isMemberClass ? 1 : 0) && 
cc.isVisible(v))
-                               return cc.makeAccessible(v);
+                               return cc.accessible(v);
                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 24a13b0..9361919 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
@@ -126,15 +126,28 @@ public final class ConstructorInfo extends ExecutableInfo 
implements Comparable<
 
        /**
         * Shortcut for calling the new-instance method on the underlying 
constructor.
+        * 
+        * @param args the arguments used for the method call.
+        *      <br>Extra parameters are ignored.
+        *      <br>Missing parameters are set to null.
+        * @return The object returned from the constructor.
+        * @throws ExecutableException Exception occurred on invoked 
constructor/method/field.
+        */
+       public <T> T invokeFuzzy(Object...args) throws ExecutableException {
+               return invoke(ClassUtils.getMatchingArgs(c.getParameterTypes(), 
args));
+       }
+
+       /**
+        * Shortcut for calling the new-instance method on the underlying 
constructor.
         *
-        * @param args the arguments used for the method call
+        * @param args the arguments used for the method call.
         * @return The object returned from the constructor.
         * @throws ExecutableException Exception occurred on invoked 
constructor/method/field.
         */
        @SuppressWarnings("unchecked")
        public <T> T invoke(Object...args) throws ExecutableException {
                try {
-                       return 
(T)c.newInstance(ClassUtils.getMatchingArgs(c.getParameterTypes(), args));
+                       return (T)c.newInstance(args);
                } catch (InvocationTargetException e) {
                        throw new ExecutableException(e.getTargetException());
                } catch (Exception e) {
@@ -153,7 +166,7 @@ public final class ConstructorInfo extends ExecutableInfo 
implements Comparable<
         *      The same constructor if visibility requirements met, or 
<jk>null</jk> if visibility requirement not
         *      met or call to {@link Constructor#setAccessible(boolean)} 
throws a security exception.
         */
-       public ConstructorInfo makeAccessible(Visibility v) {
+       public ConstructorInfo accessible(Visibility v) {
                if (v.transform(c) == null)
                        return null;
                return this;
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
index c12c720..5fab53b 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
@@ -23,6 +23,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Subclass of {@link Serializer} for byte-based serializers.
@@ -74,8 +75,14 @@ public abstract class OutputStreamSerializer extends 
Serializer {
                public abstract Builder copy();
 
                @Override /* Context.Builder */
-               public OutputStreamSerializer build() {
-                       return (OutputStreamSerializer)super.build();
+               public abstract OutputStreamSerializer build();
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               binaryFormat
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
index 96a6f2c..944bbf5 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
@@ -26,6 +26,7 @@ import org.apache.juneau.annotation.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Parent class for all Juneau serializers.
@@ -165,8 +166,27 @@ public abstract class Serializer extends 
BeanTraverseContext {
                public abstract Builder copy();
 
                @Override /* Context.Builder */
-               public Serializer build() {
-                       return (Serializer)super.build();
+               public abstract Serializer build();
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               produces,
+                               accept,
+                               addBeanTypes,
+                               addRootType,
+                               keepNullProperties,
+                               sortCollections,
+                               sortMaps,
+                               trimEmptyCollections,
+                               trimEmptyMaps,
+                               trimStrings,
+                               uriContext,
+                               uriRelativity,
+                               uriResolution,
+                               listener
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
index 925ae57..ea96ba0 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
@@ -27,6 +27,7 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Subclass of {@link Serializer} for character-based serializers.
@@ -96,8 +97,19 @@ public abstract class WriterSerializer extends Serializer {
                public abstract Builder copy();
 
                @Override /* Context.Builder */
-               public WriterSerializer build() {
-                       return (WriterSerializer)super.build();
+               public abstract WriterSerializer build();
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               fileCharset,
+                               streamCharset,
+                               maxIndent,
+                               quoteChar,
+                               quoteCharOverride,
+                               useWhitespace
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java
index ece42f0..ccea016 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java
@@ -24,6 +24,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
+import org.apache.juneau.utils.*;
 import org.apache.juneau.xml.*;
 
 /**
@@ -64,6 +65,8 @@ public class SoapXmlSerializer extends XmlSerializer 
implements SoapXmlMetaProvi
        @FluentSetters
        public static class Builder extends XmlSerializer.Builder {
 
+               private static final Cache<HashKey,SoapXmlSerializer> CACHE = 
Cache.of(HashKey.class, SoapXmlSerializer.class).build();
+
                String soapAction;
 
                /**
@@ -104,7 +107,15 @@ public class SoapXmlSerializer extends XmlSerializer 
implements SoapXmlMetaProvi
 
                @Override /* Context.Builder */
                public SoapXmlSerializer build() {
-                       return (SoapXmlSerializer)super.build();
+                       return build(SoapXmlSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               soapAction
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParser.java
index 2b3aed8..23de8c5 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParser.java
@@ -27,6 +27,7 @@ import org.apache.juneau.http.header.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Parses UON (a notation for URL-encoded query parameter values) text into 
POJO models.
@@ -88,6 +89,8 @@ public class UonParser extends ReaderParser implements 
HttpPartParser, UonMetaPr
        @FluentSetters
        public static class Builder extends ReaderParser.Builder {
 
+               private static final Cache<HashKey,UonParser> CACHE = 
Cache.of(HashKey.class, UonParser.class).build();
+
                boolean decoding, validateEnd;
 
                /**
@@ -130,7 +133,16 @@ public class UonParser extends ReaderParser implements 
HttpPartParser, UonMetaPr
 
                @Override /* Context.Builder */
                public UonParser build() {
-                       return (UonParser)super.build();
+                       return build(UonParser.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               decoding,
+                               validateEnd
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java
index 13f0e68..52b7d49 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java
@@ -28,6 +28,7 @@ import org.apache.juneau.http.header.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Serializes POJO models to UON (a notation for URL-encoded query parameter 
values).
@@ -216,6 +217,8 @@ public class UonSerializer extends WriterSerializer 
implements HttpPartSerialize
        @FluentSetters
        public static class Builder extends WriterSerializer.Builder {
 
+               private static final Cache<HashKey,UonSerializer> CACHE = 
Cache.of(HashKey.class, UonSerializer.class).build();
+
                boolean addBeanTypesUon, encoding;
                ParamFormat paramFormat;
                Character quoteCharUon;
@@ -266,7 +269,18 @@ public class UonSerializer extends WriterSerializer 
implements HttpPartSerialize
 
                @Override /* Context.Builder */
                public UonSerializer build() {
-                       return (UonSerializer)super.build();
+                       return build(UonSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               addBeanTypesUon,
+                               encoding,
+                               paramFormat,
+                               quoteCharUon
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
index a39a208..8358cf3 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
@@ -26,6 +26,7 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.uon.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Parses URL-encoded text into POJO models.
@@ -73,6 +74,8 @@ public class UrlEncodingParser extends UonParser implements 
UrlEncodingMetaProvi
        @FluentSetters
        public static class Builder extends UonParser.Builder {
 
+               private static final Cache<HashKey,UrlEncodingParser> CACHE = 
Cache.of(HashKey.class, UrlEncodingParser.class).build();
+
                boolean expandedParams;
 
                /**
@@ -113,7 +116,15 @@ public class UrlEncodingParser extends UonParser 
implements UrlEncodingMetaProvi
 
                @Override /* Context.Builder */
                public UrlEncodingParser build() {
-                       return (UrlEncodingParser)super.build();
+                       return build(UrlEncodingParser.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               expandedParams
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
index 980d65f..8b0d87e 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
@@ -26,6 +26,7 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.uon.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Serializes POJO models to URL-encoded notation with UON-encoded values (a 
notation for URL-encoded query paramter values).
@@ -208,6 +209,8 @@ public class UrlEncodingSerializer extends UonSerializer 
implements UrlEncodingM
        @FluentSetters
        public static class Builder extends UonSerializer.Builder {
 
+               private static final Cache<HashKey,UrlEncodingSerializer> CACHE 
= Cache.of(HashKey.class, UrlEncodingSerializer.class).build();
+
                boolean expandedParams;
 
                /**
@@ -247,7 +250,15 @@ public class UrlEncodingSerializer extends UonSerializer 
implements UrlEncodingM
 
                @Override /* Context.Builder */
                public UrlEncodingSerializer build() {
-                       return (UrlEncodingSerializer)super.build();
+                       return build(UrlEncodingSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               expandedParams
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParser.java
index ad86a8e..4a7edc6 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParser.java
@@ -31,6 +31,7 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Parses text generated by the {@link XmlSerializer} class back into a POJO 
model.
@@ -72,6 +73,8 @@ public class XmlParser extends ReaderParser implements 
XmlMetaProvider {
        @FluentSetters
        public static class Builder extends ReaderParser.Builder {
 
+               private static final Cache<HashKey,XmlParser> CACHE = 
Cache.of(HashKey.class, XmlParser.class).build();
+
                boolean preserveRootElement, validating;
                Class<? extends XMLEventAllocator> eventAllocator;
                Class<? extends XMLReporter> reporter;
@@ -126,7 +129,19 @@ public class XmlParser extends ReaderParser implements 
XmlMetaProvider {
 
                @Override /* Context.Builder */
                public XmlParser build() {
-                       return (XmlParser)super.build();
+                       return build(XmlParser.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               preserveRootElement,
+                               validating,
+                               eventAllocator,
+                               reporter,
+                               resolver
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java
index 0d07c35..71d3bd3 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java
@@ -28,6 +28,7 @@ import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Serializes POJO models to XML.
@@ -240,6 +241,8 @@ public class XmlSerializer extends WriterSerializer 
implements XmlMetaProvider {
        @FluentSetters
        public static class Builder extends WriterSerializer.Builder {
 
+               private static final Cache<HashKey,XmlSerializer> CACHE = 
Cache.of(HashKey.class, XmlSerializer.class).build();
+
                boolean addBeanTypesXml, addNamespaceUrisToRoot, 
disableAutoDetectNamespaces, enableNamespaces;
                Namespace defaultNamespace;
                List<Namespace> namespaces;
@@ -297,7 +300,20 @@ public class XmlSerializer extends WriterSerializer 
implements XmlMetaProvider {
 
                @Override /* Context.Builder */
                public XmlSerializer build() {
-                       return (XmlSerializer)super.build();
+                       return build(XmlSerializer.class, CACHE);
+               }
+
+               @Override /* Context.Builder */
+               public HashKey hashKey() {
+                       return HashKey.of(
+                               super.hashKey(),
+                               addBeanTypesXml,
+                               addNamespaceUrisToRoot,
+                               disableAutoDetectNamespaces,
+                               enableNamespaces,
+                               defaultNamespace,
+                               namespaces
+                       );
                }
 
                
//-----------------------------------------------------------------------------------------------------------------
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 9d146ca..edc27b0 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
@@ -2558,6 +2558,11 @@ public class ThirdPartyProxyTest extends RestTestcase {
                        public Builder copy() {
                                return new Builder(this);
                        }
+
+                       @Override
+                       public DummyPartSerializer build() {
+                               return new DummyPartSerializer(this);
+                       }
                }
 
                @Override
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index d4e6848..b357035 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -1100,7 +1100,7 @@ public class RestClient extends BeanContextable 
implements HttpClient, Closeable
 
                @Override /* Context.Builder */
                public RestClient build() {
-                       return (RestClient)super.build();
+                       return build(RestClient.class, null);
                }
 
                /**
@@ -1109,10 +1109,9 @@ public class RestClient extends BeanContextable 
implements HttpClient, Closeable
                 * @param c The subtype to create.
                 * @return A new client.
                 */
-               @SuppressWarnings("unchecked")
                public <T extends RestClient> T build(Class<T> c) {
                        type(c);
-                       return (T)super.build();
+                       return build(c, null);
                }
 
                
//------------------------------------------------------------------------------------------------------------------
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 720a6dd..4ace814 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
@@ -307,7 +307,7 @@ public class RestContext extends Context {
                        try {
                                return 
BeanCreator.of(RestContext.class).outer(resource.get()).store(beanStore()).builder(this).type(getType().orElse(RestContext.class)).run();
                        } catch (Exception e) {
-                               throw toHttpException(e, 
InternalServerError.class);
+                               throw new InternalServerError(e, "Could not 
instantiate RestContext.");
                        }
                }
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/reflection/ConstructorInfoTest.java
 
b/juneau-utest/src/test/java/org/apache/juneau/reflection/ConstructorInfoTest.java
index fa4b8bd..53d6d33 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/reflection/ConstructorInfoTest.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/reflection/ConstructorInfoTest.java
@@ -117,14 +117,14 @@ public class ConstructorInfoTest {
 
        @Test
        public void invoke() throws Exception {
-               assertEquals(null, b_c1.invoke().toString());
-               assertEquals("foo", b_c2.invoke("foo").toString());
+               assertEquals(null, b_c1.invokeFuzzy().toString());
+               assertEquals("foo", b_c2.invokeFuzzy("foo").toString());
        }
 
        @Test
-       public void makeAccessible() throws Exception {
-               b_c3.makeAccessible(Visibility.PROTECTED);
-               assertEquals(null, b_c3.invoke(123).toString());
+       public void accessible() throws Exception {
+               b_c3.accessible(Visibility.PROTECTED);
+               assertEquals(null, b_c3.invokeFuzzy(123).toString());
        }
 
        @Test
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
index 01c5ae1..69beef3 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
@@ -91,7 +91,7 @@ public class Rest_Context_Test {
 
        @Test
        public void a05_invalidConstructor() throws Exception {
-               assertThrown(()->client(A5.class)).messages().contains("Error 
occurred trying to create context.");
+               assertThrown(()->client(A5.class)).messages().contains("Could 
not instantiate RestContext.");
        }
 
        
//------------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/testutils/MockReaderParser.java 
b/juneau-utest/src/test/java/org/apache/juneau/testutils/MockReaderParser.java
index bd45ec0..6df6d6a 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/testutils/MockReaderParser.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/testutils/MockReaderParser.java
@@ -105,6 +105,11 @@ public class MockReaderParser extends ReaderParser 
implements HttpPartParser {
                public Builder copy() {
                        return new Builder(this);
                }
+
+               @Override
+               public MockReaderParser build() {
+                       return build(MockReaderParser.class, null);
+               }
        }
 
        @Override
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/testutils/MockStreamParser.java 
b/juneau-utest/src/test/java/org/apache/juneau/testutils/MockStreamParser.java
index ea7e0de..214cd51 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/testutils/MockStreamParser.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/testutils/MockStreamParser.java
@@ -76,6 +76,11 @@ public class MockStreamParser extends InputStreamParser {
                public Builder copy() {
                        throw new NoSuchMethodError("Not implemented.");
                }
+
+               @Override
+               public MockStreamParser build() {
+                       return build(MockStreamParser.class, null);
+               }
        }
 
        @Override
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/testutils/MockStreamSerializer.java
 
b/juneau-utest/src/test/java/org/apache/juneau/testutils/MockStreamSerializer.java
index d1d3348..993a5f2 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/testutils/MockStreamSerializer.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/testutils/MockStreamSerializer.java
@@ -85,6 +85,11 @@ public class MockStreamSerializer extends 
OutputStreamSerializer {
                public Builder copy() {
                        throw new NoSuchMethodError("Not implemented.");
                }
+
+               @Override
+               public MockStreamSerializer build() {
+                       return build(MockStreamSerializer.class, null);
+               }
        }
 
        @Override
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/testutils/MockWriterSerializer.java
 
b/juneau-utest/src/test/java/org/apache/juneau/testutils/MockWriterSerializer.java
index 0f1b01e..a55fe32 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/testutils/MockWriterSerializer.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/testutils/MockWriterSerializer.java
@@ -152,6 +152,11 @@ public class MockWriterSerializer extends WriterSerializer 
implements HttpPartSe
                public Builder copy() {
                        return new Builder(this);
                }
+
+               @Override
+               public MockWriterSerializer build() {
+                       return build(MockWriterSerializer.class, null);
+               }
        }
 
        @Override

Reply via email to