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 80b7a3bcaa org.apache.juneau.common.reflect API improvements
80b7a3bcaa is described below

commit 80b7a3bcaa2de750506a31d30c70b993ac3fbdd1
Author: James Bognar <[email protected]>
AuthorDate: Fri Nov 21 13:23:50 2025 -0500

    org.apache.juneau.common.reflect API improvements
---
 .../apache/juneau/common/collections/Cache.java    |  73 +++++------
 .../apache/juneau/common/collections/Cache2.java   |  68 ++++------
 .../apache/juneau/common/collections/Cache3.java   |  45 ++++---
 .../apache/juneau/common/collections/Cache4.java   |  45 ++++---
 .../apache/juneau/common/collections/Cache5.java   |  45 ++++---
 .../juneau/common/collections/CacheMode.java       | 128 ++++++++++++++++++
 .../juneau/common/reflect/AnnotationProvider.java  | 146 ++++++++++++++++-----
 .../juneau/common/utils/MimeTypeDetector.java      |  26 ++--
 .../juneau/common/collections/Cache2_Test.java     |   4 +-
 .../juneau/common/collections/Cache3_Test.java     |   4 +-
 .../juneau/common/collections/Cache4_Test.java     |   4 +-
 .../juneau/common/collections/Cache5_Test.java     |   4 +-
 .../juneau/common/collections/Cache_Test.java      |  10 +-
 .../juneau/common/utils/MimeTypeDetector_Test.java |   7 +-
 14 files changed, 415 insertions(+), 194 deletions(-)

diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache.java
index 5c48fd291c..7094c2fd62 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache.java
@@ -16,6 +16,7 @@
  */
 package org.apache.juneau.common.collections;
 
+import static org.apache.juneau.common.collections.CacheMode.*;
 import static org.apache.juneau.common.utils.AssertionUtils.*;
 import static org.apache.juneau.common.utils.SystemUtils.*;
 import static org.apache.juneau.common.utils.Utils.*;
@@ -94,7 +95,7 @@ import org.apache.juneau.common.function.*;
  * <p>
  * The following system properties can be used to configure default cache 
behavior:
  * <ul class='spaced-list'>
- *     <li><c>juneau.cache.disable</c> - Disables all caching (default: 
<jk>false</jk>)
+ *     <li><c>juneau.cache.mode</c> - Cache mode: NONE/WEAK/FULL (default: 
FULL, case-insensitive)
  *     <li><c>juneau.cache.maxSize</c> - Maximum cache size before eviction 
(default: 1000)
  *     <li><c>juneau.cache.logOnExit</c> - Log cache statistics on shutdown 
(default: <jk>false</jk>)
  * </ul>
@@ -152,7 +153,7 @@ import org.apache.juneau.common.function.*;
 public class Cache<K,V> {
 
        // Internal map with Tuple1 keys for content-based equality (especially 
for arrays)
-       private final ConcurrentHashMap<Tuple1<K>,V> map = new 
ConcurrentHashMap<>();
+       private final Map<Tuple1<K>,V> map;
 
        /**
         * Cache of Tuple1 wrapper objects to minimize object creation on 
repeated get/put calls.
@@ -161,7 +162,7 @@ public class Cache<K,V> {
         * Uses WeakHashMap so wrappers can be GC'd when keys are no longer 
referenced.
         * This provides a significant performance improvement for caches with 
repeated key access.
         */
-       private final Map<K,Tuple1<K>> wrapperCache = synchronizedMap(new 
WeakHashMap<>());
+       private final Map<K,Tuple1<K>> wrapperCache;
 
        /**
         * Gets or creates a Tuple1 wrapper for the given key.
@@ -206,14 +207,14 @@ public class Cache<K,V> {
         * @param <V> The value type.
         */
        public static class Builder<K,V> {
-               boolean disableCaching;
+               CacheMode cacheMode;
                int maxSize;
                String id;
                boolean logOnExit;
                Function<K,V> supplier;
 
                Builder() {
-                       disableCaching = env("juneau.cache.disable", false);
+                       cacheMode = CacheMode.parse(env("juneau.cache.mode", 
"FULL"));
                        maxSize = env("juneau.cache.maxSize", 1000);
                        logOnExit = env("juneau.cache.logOnExit", false);
                        id = "Cache";
@@ -229,50 +230,39 @@ public class Cache<K,V> {
                }
 
                /**
-                * Disables caching entirely.
+                * Sets the caching mode for this cache.
                 *
                 * <p>
-                * When disabled, the {@link Cache#get(Object)} and {@link 
Cache#get(Object, Supplier)} methods
-                * will always invoke the supplier and never store or retrieve 
values from the cache.
-                *
-                * <p>
-                * This is useful for:
+                * Available modes:
                 * <ul>
-                *      <li>Testing scenarios where you want fresh computation 
each time
-                *      <li>Development environments where caching might hide 
issues
-                *      <li>Temporarily disabling caching without code changes
+                *      <li>{@link CacheMode#NONE NONE} - No caching (always 
invoke supplier)
+                *      <li>{@link CacheMode#WEAK WEAK} - Weak caching (uses 
{@link WeakHashMap})
+                *      <li>{@link CacheMode#FULL FULL} - Full caching (uses 
{@link ConcurrentHashMap}, default)
                 * </ul>
                 *
-                * @return This object for method chaining.
-                */
-               public Builder<K,V> disableCaching() {
-                       disableCaching = true;
-                       return this;
-               }
-
-               /**
-                * Conditionally disables or enables caching.
-                *
-                * <p>
-                * When disabled, the {@link Cache#get(Object)} and {@link 
Cache#get(Object, Supplier)} methods
-                * will always invoke the supplier and never store or retrieve 
values from the cache.
-                *
-                * <p>
-                * This is typically used when the disable flag comes from an 
external configuration or system property.
-                *
                 * <h5 class='section'>Example:</h5>
                 * <p class='bjava'>
-                *      Cache&lt;String,Object&gt; <jv>cache</jv> = 
Cache.<jsm>of</jsm>(String.<jk>class</jk>, Object.<jk>class</jk>)
-                *              
.disableCaching(Boolean.<jsm>getBoolean</jsm>(<js>"myapp.disableCache"</js>))
+                *      <jc>// No caching for testing</jc>
+                *      Cache&lt;String,Object&gt; <jv>cache1</jv> = 
Cache.<jsm>of</jsm>(String.<jk>class</jk>, Object.<jk>class</jk>)
+                *              .cacheMode(CacheMode.<jsf>NONE</jsf>)
+                *              .build();
+                *
+                *      <jc>// Weak caching for Class metadata</jc>
+                *      Cache&lt;Class&lt;?&gt;,ClassMeta&gt; <jv>cache2</jv> = 
Cache.<jsm>of</jsm>(Class.<jk>class</jk>, ClassMeta.<jk>class</jk>)
+                *              .cacheMode(CacheMode.<jsf>WEAK</jsf>)
+                *              .build();
+                *
+                *      <jc>// Full caching (default)</jc>
+                *      Cache&lt;String,Pattern&gt; <jv>cache3</jv> = 
Cache.<jsm>of</jsm>(String.<jk>class</jk>, Pattern.<jk>class</jk>)
+                *              .cacheMode(CacheMode.<jsf>FULL</jsf>)
                 *              .build();
                 * </p>
                 *
-                * @param value If <jk>true</jk>, caching is disabled. If 
<jk>false</jk>, caching is enabled (default).
+                * @param value The caching mode.
                 * @return This object for method chaining.
-                * @see #disableCaching()
                 */
-               public Builder<K,V> disableCaching(boolean value) {
-                       disableCaching = value;
+               public Builder<K,V> cacheMode(CacheMode value) {
+                       cacheMode = value;
                        return this;
                }
 
@@ -432,8 +422,15 @@ public class Cache<K,V> {
         */
        protected Cache(Builder<K,V> builder) {
                this.maxSize = builder.maxSize;
-               this.disableCaching = builder.disableCaching;
+               this.disableCaching = builder.cacheMode == NONE;
                this.supplier = builder.supplier != null ? builder.supplier : 
(K)->null;
+               if (builder.cacheMode == WEAK) {
+                       this.map = synchronizedMap(new WeakHashMap<>());
+                       this.wrapperCache = synchronizedMap(new 
WeakHashMap<>());
+               } else {
+                       this.map = new ConcurrentHashMap<>();
+                       this.wrapperCache = synchronizedMap(new 
WeakHashMap<>());
+               }
                if (builder.logOnExit) {
                        shutdownMessage(() -> builder.id + ":  hits=" + 
cacheHits.get() + ", misses: " + size());
                }
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache2.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache2.java
index 9d90fc8e48..ab8bfda19b 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache2.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache2.java
@@ -16,10 +16,14 @@
  */
 package org.apache.juneau.common.collections;
 
+import static org.apache.juneau.common.collections.CacheMode.*;
+
 import static org.apache.juneau.common.utils.AssertionUtils.*;
 import static org.apache.juneau.common.utils.SystemUtils.*;
 import static org.apache.juneau.common.utils.Utils.*;
 
+import java.util.*;
+import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
 
 import org.apache.juneau.common.function.*;
@@ -78,7 +82,7 @@ import org.apache.juneau.common.function.*;
  * <p>
  * The following system properties can be used to configure default cache 
behavior:
  * <ul class='spaced-list'>
- *     <li><c>juneau.cache.disable</c> - Disables all caching (default: 
<jk>false</jk>)
+ *     <li><c>juneau.cache.mode</c> - Cache mode: NONE/WEAK/FULL (default: 
FULL, case-insensitive)
  *     <li><c>juneau.cache.maxSize</c> - Maximum cache size before eviction 
(default: 1000)
  *     <li><c>juneau.cache.logOnExit</c> - Log cache statistics on shutdown 
(default: <jk>false</jk>)
  * </ul>
@@ -133,7 +137,7 @@ import org.apache.juneau.common.function.*;
 public class Cache2<K1,K2,V> {
 
        // Internal map with Tuple2 keys for content-based equality (especially 
for arrays)
-       private final java.util.concurrent.ConcurrentHashMap<Tuple2<K1,K2>,V> 
map = new java.util.concurrent.ConcurrentHashMap<>();
+       private final java.util.Map<Tuple2<K1,K2>,V> map;
 
        /**
         * Builder for creating configured {@link Cache2} instances.
@@ -157,14 +161,14 @@ public class Cache2<K1,K2,V> {
         * @param <V> The value type.
         */
        public static class Builder<K1,K2,V> {
-               boolean disableCaching;
+               CacheMode cacheMode;
                int maxSize;
                String id;
                boolean logOnExit;
                Function2<K1,K2,V> supplier;
 
                Builder() {
-                       disableCaching = env("juneau.cache.disable", false);
+                       cacheMode = CacheMode.parse(env("juneau.cache.mode", 
"FULL"));
                        maxSize = env("juneau.cache.maxSize", 1000);
                        logOnExit = env("juneau.cache.logOnExit", false);
                        id = "Cache2";
@@ -180,50 +184,21 @@ public class Cache2<K1,K2,V> {
                }
 
                /**
-                * Disables caching entirely.
-                *
-                * <p>
-                * When disabled, the {@link Cache2#get(Object, Object)} and
-                * {@link Cache2#get(Object, Object, 
java.util.function.Supplier)} methods will always invoke
-                * the supplier and never store or retrieve values from the 
cache.
+                * Sets the caching mode for this cache.
                 *
                 * <p>
-                * This is useful for:
+                * Available modes:
                 * <ul>
-                *      <li>Testing scenarios where you want fresh computation 
each time
-                *      <li>Development environments where caching might hide 
issues
-                *      <li>Temporarily disabling caching without code changes
+                *      <li>{@link CacheMode#NONE NONE} - No caching (always 
invoke supplier)
+                *      <li>{@link CacheMode#WEAK WEAK} - Weak caching (uses 
{@link WeakHashMap})
+                *      <li>{@link CacheMode#FULL FULL} - Full caching (uses 
{@link ConcurrentHashMap}, default)
                 * </ul>
                 *
+                * @param value The caching mode.
                 * @return This object for method chaining.
                 */
-               public Builder<K1,K2,V> disableCaching() {
-                       disableCaching = true;
-                       return this;
-               }
-
-               /**
-                * Optionally disables caching based on the provided flag.
-                *
-                * <p>
-                * When disabled, the {@link Cache2#get(Object, Object)} and
-                * {@link Cache2#get(Object, Object, 
java.util.function.Supplier)} methods will always invoke
-                * the supplier and never store or retrieve values from the 
cache.
-                *
-                * <h5 class='section'>Example:</h5>
-                * <p class='bjava'>
-                *      <jk>boolean</jk> <jv>disable</jv> = 
env(<js>"disable.caching"</js>, <jk>false</jk>);
-                *      Cache2&lt;String,String,Config&gt; <jv>cache</jv> = 
Cache2
-                *              .<jsm>of</jsm>(String.<jk>class</jk>, 
String.<jk>class</jk>, Config.<jk>class</jk>)
-                *              .disableCaching(<jv>disable</jv>)
-                *              .build();
-                * </p>
-                *
-                * @param value If <jk>true</jk>, disables caching.
-                * @return This object for method chaining.
-                */
-               public Builder<K1,K2,V> disableCaching(boolean value) {
-                       disableCaching = value;
+               public Builder<K1,K2,V> cacheMode(CacheMode value) {
+                       cacheMode = value;
                        return this;
                }
 
@@ -377,7 +352,7 @@ public class Cache2<K1,K2,V> {
        }
 
        private final int maxSize;
-       private final boolean disableCaching;
+       private final CacheMode cacheMode;
        private final Function2<K1,K2,V> supplier;
        private final AtomicInteger cacheHits = new AtomicInteger();
 
@@ -388,8 +363,13 @@ public class Cache2<K1,K2,V> {
         */
        protected Cache2(Builder<K1,K2,V> builder) {
                this.maxSize = builder.maxSize;
-               this.disableCaching = builder.disableCaching;
+               this.cacheMode = builder.cacheMode;
                this.supplier = builder.supplier;
+               if (builder.cacheMode == WEAK) {
+                       this.map = Collections.synchronizedMap(new 
WeakHashMap<>());
+               } else {
+                       this.map = new ConcurrentHashMap<>();
+               }
                if (builder.logOnExit) {
                        shutdownMessage(() -> builder.id + ":  hits=" + 
cacheHits.get() + ", misses: " + size());
                }
@@ -467,7 +447,7 @@ public class Cache2<K1,K2,V> {
         */
        public V get(K1 key1, K2 key2, java.util.function.Supplier<V> supplier) 
{
                assertArgsNotNull("key1", key1, "key2", key2);
-               if (disableCaching)
+               if (cacheMode == NONE)
                        return supplier.get();
                Tuple2<K1,K2> wrapped = Tuple2.of(key1, key2);
                V v = map.get(wrapped);
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache3.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache3.java
index a018e4122e..a134446141 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache3.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache3.java
@@ -16,10 +16,14 @@
  */
 package org.apache.juneau.common.collections;
 
+import static org.apache.juneau.common.collections.CacheMode.*;
+
 import static org.apache.juneau.common.utils.AssertionUtils.*;
 import static org.apache.juneau.common.utils.SystemUtils.*;
 import static org.apache.juneau.common.utils.Utils.*;
 
+import java.util.*;
+import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
 
 import org.apache.juneau.common.function.*;
@@ -77,7 +81,7 @@ import org.apache.juneau.common.function.*;
 public class Cache3<K1,K2,K3,V> {
 
        // Internal map with Tuple3 keys for content-based equality (especially 
for arrays)
-       private final 
java.util.concurrent.ConcurrentHashMap<Tuple3<K1,K2,K3>,V> map = new 
java.util.concurrent.ConcurrentHashMap<>();
+       private final java.util.Map<Tuple3<K1,K2,K3>,V> map;
 
        /**
         * Builder for creating configured {@link Cache3} instances.
@@ -88,14 +92,14 @@ public class Cache3<K1,K2,K3,V> {
         * @param <V> The value type.
         */
        public static class Builder<K1,K2,K3,V> {
-               boolean disableCaching;
+               CacheMode cacheMode;
                int maxSize;
                String id;
                boolean logOnExit;
                Function3<K1,K2,K3,V> supplier;
 
                Builder() {
-                       disableCaching = env("juneau.cache.disable", false);
+                       cacheMode = CacheMode.parse(env("juneau.cache.mode", 
"FULL"));
                        maxSize = env("juneau.cache.maxSize", 1000);
                        logOnExit = env("juneau.cache.logOnExit", false);
                        id = "Cache3";
@@ -111,23 +115,21 @@ public class Cache3<K1,K2,K3,V> {
                }
 
                /**
-                * Disables caching entirely.
+                * Sets the caching mode for this cache.
                 *
-                * @return This object for method chaining.
-                */
-               public Builder<K1,K2,K3,V> disableCaching() {
-                       disableCaching = true;
-                       return this;
-               }
-
-               /**
-                * Optionally disables caching based on the provided flag.
+                * <p>
+                * Available modes:
+                * <ul>
+                *      <li>{@link CacheMode#NONE NONE} - No caching (always 
invoke supplier)
+                *      <li>{@link CacheMode#WEAK WEAK} - Weak caching (uses 
{@link WeakHashMap})
+                *      <li>{@link CacheMode#FULL FULL} - Full caching (uses 
{@link ConcurrentHashMap}, default)
+                * </ul>
                 *
-                * @param value If <jk>true</jk>, disables caching.
+                * @param value The caching mode.
                 * @return This object for method chaining.
                 */
-               public Builder<K1,K2,K3,V> disableCaching(boolean value) {
-                       disableCaching = value;
+               public Builder<K1,K2,K3,V> cacheMode(CacheMode value) {
+                       cacheMode = value;
                        return this;
                }
 
@@ -218,7 +220,7 @@ public class Cache3<K1,K2,K3,V> {
        }
 
        private final int maxSize;
-       private final boolean disableCaching;
+       private final CacheMode cacheMode;
        private final Function3<K1,K2,K3,V> supplier;
        private final AtomicInteger cacheHits = new AtomicInteger();
 
@@ -229,8 +231,13 @@ public class Cache3<K1,K2,K3,V> {
         */
        protected Cache3(Builder<K1,K2,K3,V> builder) {
                this.maxSize = builder.maxSize;
-               this.disableCaching = builder.disableCaching;
+               this.cacheMode = builder.cacheMode;
                this.supplier = builder.supplier;
+               if (builder.cacheMode == WEAK) {
+                       this.map = Collections.synchronizedMap(new 
WeakHashMap<>());
+               } else {
+                       this.map = new ConcurrentHashMap<>();
+               }
                if (builder.logOnExit) {
                        shutdownMessage(() -> builder.id + ":  hits=" + 
cacheHits.get() + ", misses: " + size());
                }
@@ -263,7 +270,7 @@ public class Cache3<K1,K2,K3,V> {
         */
        public V get(K1 key1, K2 key2, K3 key3, java.util.function.Supplier<V> 
supplier) {
                assertArgsNotNull("key1", key1, "key2", key2, "key3", key3);
-               if (disableCaching)
+               if (cacheMode == NONE)
                        return supplier.get();
                Tuple3<K1,K2,K3> wrapped = Tuple3.of(key1, key2, key3);
                V v = map.get(wrapped);
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache4.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache4.java
index 3fda8bd97c..e61958a23a 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache4.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache4.java
@@ -16,10 +16,14 @@
  */
 package org.apache.juneau.common.collections;
 
+import static org.apache.juneau.common.collections.CacheMode.*;
+
 import static org.apache.juneau.common.utils.AssertionUtils.*;
 import static org.apache.juneau.common.utils.SystemUtils.*;
 import static org.apache.juneau.common.utils.Utils.*;
 
+import java.util.*;
+import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
 
 import org.apache.juneau.common.function.*;
@@ -63,7 +67,7 @@ import org.apache.juneau.common.function.*;
 public class Cache4<K1,K2,K3,K4,V> {
 
        // Internal map with Tuple4 keys for content-based equality (especially 
for arrays)
-       private final 
java.util.concurrent.ConcurrentHashMap<Tuple4<K1,K2,K3,K4>,V> map = new 
java.util.concurrent.ConcurrentHashMap<>();
+       private final java.util.Map<Tuple4<K1,K2,K3,K4>,V> map;
 
        /**
         * Builder for creating configured {@link Cache4} instances.
@@ -75,14 +79,14 @@ public class Cache4<K1,K2,K3,K4,V> {
         * @param <V> The value type.
         */
        public static class Builder<K1,K2,K3,K4,V> {
-               boolean disableCaching;
+               CacheMode cacheMode;
                int maxSize;
                String id;
                boolean logOnExit;
                Function4<K1,K2,K3,K4,V> supplier;
 
                Builder() {
-                       disableCaching = env("juneau.cache.disable", false);
+                       cacheMode = CacheMode.parse(env("juneau.cache.mode", 
"FULL"));
                        maxSize = env("juneau.cache.maxSize", 1000);
                        logOnExit = env("juneau.cache.logOnExit", false);
                        id = "Cache4";
@@ -98,23 +102,21 @@ public class Cache4<K1,K2,K3,K4,V> {
                }
 
                /**
-                * Disables caching entirely.
+                * Sets the caching mode for this cache.
                 *
-                * @return This object for method chaining.
-                */
-               public Builder<K1,K2,K3,K4,V> disableCaching() {
-                       disableCaching = true;
-                       return this;
-               }
-
-               /**
-                * Optionally disables caching based on the provided flag.
+                * <p>
+                * Available modes:
+                * <ul>
+                *      <li>{@link CacheMode#NONE NONE} - No caching (always 
invoke supplier)
+                *      <li>{@link CacheMode#WEAK WEAK} - Weak caching (uses 
{@link WeakHashMap})
+                *      <li>{@link CacheMode#FULL FULL} - Full caching (uses 
{@link ConcurrentHashMap}, default)
+                * </ul>
                 *
-                * @param value If <jk>true</jk>, disables caching.
+                * @param value The caching mode.
                 * @return This object for method chaining.
                 */
-               public Builder<K1,K2,K3,K4,V> disableCaching(boolean value) {
-                       disableCaching = value;
+               public Builder<K1,K2,K3,K4,V> cacheMode(CacheMode value) {
+                       cacheMode = value;
                        return this;
                }
 
@@ -208,7 +210,7 @@ public class Cache4<K1,K2,K3,K4,V> {
        }
 
        private final int maxSize;
-       private final boolean disableCaching;
+       private final CacheMode cacheMode;
        private final Function4<K1,K2,K3,K4,V> supplier;
        private final AtomicInteger cacheHits = new AtomicInteger();
 
@@ -219,8 +221,13 @@ public class Cache4<K1,K2,K3,K4,V> {
         */
        protected Cache4(Builder<K1,K2,K3,K4,V> builder) {
                this.maxSize = builder.maxSize;
-               this.disableCaching = builder.disableCaching;
+               this.cacheMode = builder.cacheMode;
                this.supplier = builder.supplier;
+               if (builder.cacheMode == WEAK) {
+                       this.map = Collections.synchronizedMap(new 
WeakHashMap<>());
+               } else {
+                       this.map = new ConcurrentHashMap<>();
+               }
                if (builder.logOnExit) {
                        shutdownMessage(() -> builder.id + ":  hits=" + 
cacheHits.get() + ", misses: " + size());
                }
@@ -255,7 +262,7 @@ public class Cache4<K1,K2,K3,K4,V> {
         */
        public V get(K1 key1, K2 key2, K3 key3, K4 key4, 
java.util.function.Supplier<V> supplier) {
                assertArgsNotNull("key1", key1, "key2", key2, "key3", key3, 
"key4", key4);
-               if (disableCaching)
+               if (cacheMode == NONE)
                        return supplier.get();
                Tuple4<K1,K2,K3,K4> wrapped = Tuple4.of(key1, key2, key3, key4);
                V v = map.get(wrapped);
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache5.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache5.java
index 5c49ac6dfd..ee7c5afb86 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache5.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache5.java
@@ -16,10 +16,14 @@
  */
 package org.apache.juneau.common.collections;
 
+import static org.apache.juneau.common.collections.CacheMode.*;
+
 import static org.apache.juneau.common.utils.AssertionUtils.*;
 import static org.apache.juneau.common.utils.SystemUtils.*;
 import static org.apache.juneau.common.utils.Utils.*;
 
+import java.util.*;
+import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
 
 import org.apache.juneau.common.function.*;
@@ -65,7 +69,7 @@ import org.apache.juneau.common.function.*;
 public class Cache5<K1,K2,K3,K4,K5,V> {
 
        // Internal map with Tuple5 keys for content-based equality (especially 
for arrays)
-       private final 
java.util.concurrent.ConcurrentHashMap<Tuple5<K1,K2,K3,K4,K5>,V> map = new 
java.util.concurrent.ConcurrentHashMap<>();
+       private final java.util.Map<Tuple5<K1,K2,K3,K4,K5>,V> map;
 
        /**
         * Builder for creating configured {@link Cache5} instances.
@@ -78,14 +82,14 @@ public class Cache5<K1,K2,K3,K4,K5,V> {
         * @param <V> The value type.
         */
        public static class Builder<K1,K2,K3,K4,K5,V> {
-               boolean disableCaching;
+               CacheMode cacheMode;
                int maxSize;
                String id;
                boolean logOnExit;
                Function5<K1,K2,K3,K4,K5,V> supplier;
 
                Builder() {
-                       disableCaching = env("juneau.cache.disable", false);
+                       cacheMode = CacheMode.parse(env("juneau.cache.mode", 
"FULL"));
                        maxSize = env("juneau.cache.maxSize", 1000);
                        logOnExit = env("juneau.cache.logOnExit", false);
                        id = "Cache5";
@@ -101,23 +105,21 @@ public class Cache5<K1,K2,K3,K4,K5,V> {
                }
 
                /**
-                * Disables caching entirely.
+                * Sets the caching mode for this cache.
                 *
-                * @return This object for method chaining.
-                */
-               public Builder<K1,K2,K3,K4,K5,V> disableCaching() {
-                       disableCaching = true;
-                       return this;
-               }
-
-               /**
-                * Optionally disables caching based on the provided flag.
+                * <p>
+                * Available modes:
+                * <ul>
+                *      <li>{@link CacheMode#NONE NONE} - No caching (always 
invoke supplier)
+                *      <li>{@link CacheMode#WEAK WEAK} - Weak caching (uses 
{@link WeakHashMap})
+                *      <li>{@link CacheMode#FULL FULL} - Full caching (uses 
{@link ConcurrentHashMap}, default)
+                * </ul>
                 *
-                * @param value If <jk>true</jk>, disables caching.
+                * @param value The caching mode.
                 * @return This object for method chaining.
                 */
-               public Builder<K1,K2,K3,K4,K5,V> disableCaching(boolean value) {
-                       disableCaching = value;
+               public Builder<K1,K2,K3,K4,K5,V> cacheMode(CacheMode value) {
+                       cacheMode = value;
                        return this;
                }
 
@@ -214,7 +216,7 @@ public class Cache5<K1,K2,K3,K4,K5,V> {
        }
 
        private final int maxSize;
-       private final boolean disableCaching;
+       private final CacheMode cacheMode;
        private final Function5<K1,K2,K3,K4,K5,V> supplier;
        private final AtomicInteger cacheHits = new AtomicInteger();
 
@@ -225,8 +227,13 @@ public class Cache5<K1,K2,K3,K4,K5,V> {
         */
        protected Cache5(Builder<K1,K2,K3,K4,K5,V> builder) {
                this.maxSize = builder.maxSize;
-               this.disableCaching = builder.disableCaching;
+               this.cacheMode = builder.cacheMode;
                this.supplier = builder.supplier;
+               if (builder.cacheMode == WEAK) {
+                       this.map = Collections.synchronizedMap(new 
WeakHashMap<>());
+               } else {
+                       this.map = new ConcurrentHashMap<>();
+               }
                if (builder.logOnExit) {
                        shutdownMessage(() -> builder.id + ":  hits=" + 
cacheHits.get() + ", misses: " + size());
                }
@@ -263,7 +270,7 @@ public class Cache5<K1,K2,K3,K4,K5,V> {
         */
        public V get(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, 
java.util.function.Supplier<V> supplier) {
                assertArgsNotNull("key1", key1, "key2", key2, "key3", key3, 
"key4", key4, "key5", key5);
-               if (disableCaching)
+               if (cacheMode == NONE)
                        return supplier.get();
                Tuple5<K1,K2,K3,K4,K5> wrapped = Tuple5.of(key1, key2, key3, 
key4, key5);
                V v = map.get(wrapped);
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/CacheMode.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/CacheMode.java
new file mode 100644
index 0000000000..55ddb5a9b8
--- /dev/null
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/CacheMode.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.juneau.common.collections;
+
+/**
+ * Cache modes for {@link Cache} and related cache classes.
+ *
+ * <p>
+ * Defines how cache storage is implemented and when cached entries may be 
evicted.
+ *
+ * <h5 class='section'>See Also:</h5>
+ * <ul>
+ *     <li class='jc'>{@link Cache}
+ *     <li class='jc'>{@link Cache2}
+ *     <li class='jc'>{@link Cache3}
+ *     <li class='jc'>{@link Cache4}
+ *     <li class='jc'>{@link Cache5}
+ * </ul>
+ */
+public enum CacheMode {
+
+       /**
+        * No caching - all lookups invoke the supplier.
+        *
+        * <p>
+        * When this mode is used, the cache will not store any values. Every 
call to
+        * {@link Cache#get(Object)} or {@link Cache#get(Object, 
java.util.function.Supplier)}
+        * will invoke the supplier to compute the value.
+        *
+        * <p>
+        * This mode is useful for:
+        * <ul>
+        *      <li>Testing scenarios where you want fresh computation each time
+        *      <li>Development environments where caching might hide issues
+        *      <li>Temporarily disabling caching without code changes
+        * </ul>
+        */
+       NONE,
+
+       /**
+        * Weak caching - uses {@link java.util.WeakHashMap} for storage.
+        *
+        * <p>
+        * Cache entries can be garbage collected when keys are no longer 
strongly referenced elsewhere.
+        * The WeakHashMap is wrapped with {@link 
java.util.Collections#synchronizedMap(java.util.Map)}
+        * for thread safety.
+        *
+        * <p>
+        * This mode is useful for:
+        * <ul>
+        *      <li>Caching metadata about objects that may be unloaded (e.g., 
{@link Class} objects)
+        *      <li>Memory-sensitive applications where cache entries should 
not prevent garbage collection
+        *      <li>Scenarios where keys have limited lifetimes
+        * </ul>
+        *
+        * <p>
+        * <b>Note:</b> Weak caching comes with performance trade-offs:
+        * <ul>
+        *      <li>Slightly slower access due to synchronization overhead
+        *      <li>Entries may be removed unpredictably by the garbage 
collector
+        *      <li>Not suitable for high-concurrency scenarios
+        * </ul>
+        */
+       WEAK,
+
+       /**
+        * Full caching - uses {@link java.util.concurrent.ConcurrentHashMap} 
for storage.
+        *
+        * <p>
+        * Provides the best performance with lock-free reads and writes. 
Cached entries
+        * will remain in memory until explicitly removed or the cache is 
cleared due to
+        * exceeding the maximum size.
+        *
+        * <p>
+        * This is the default and recommended mode for most use cases, 
offering:
+        * <ul>
+        *      <li>Excellent performance with no synchronization overhead for 
reads
+        *      <li>Thread-safe concurrent access
+        *      <li>Predictable memory usage (entries stay until evicted)
+        *      <li>Suitable for high-concurrency scenarios
+        * </ul>
+        */
+       FULL;
+
+       /**
+        * Parses a string value into a {@link CacheMode}.
+        *
+        * <p>
+        * Performs case-insensitive matching against the enum constant names.
+        *
+        * <h5 class='section'>Examples:</h5>
+        * <p class='bjava'>
+        *      CacheMode.<jsm>parse</jsm>(<js>"none"</js>);  <jc>// Returns 
NONE</jc>
+        *      CacheMode.<jsm>parse</jsm>(<js>"WEAK"</js>);  <jc>// Returns 
WEAK</jc>
+        *      CacheMode.<jsm>parse</jsm>(<js>"Full"</js>);  <jc>// Returns 
FULL</jc>
+        *      CacheMode.<jsm>parse</jsm>(<jk>null</jk>);    <jc>// Returns 
FULL (default)</jc>
+        *      CacheMode.<jsm>parse</jsm>(<js>"invalid"</js>); <jc>// Returns 
FULL (default)</jc>
+        * </p>
+        *
+        * @param value The string value to parse. Can be <jk>null</jk>.
+        * @return The corresponding {@link CacheMode}, or {@link #FULL} if the 
value is <jk>null</jk> or invalid.
+        */
+       public static CacheMode parse(String value) {
+               if (value == null)
+                       return FULL;
+               switch (value.toUpperCase()) {
+                       case "NONE": return NONE;
+                       case "WEAK": return WEAK;
+                       case "FULL": return FULL;
+                       default: return FULL;
+               }
+       }
+}
+
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider.java
index bb2405e533..8418e5a16d 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider.java
@@ -21,6 +21,7 @@ import static 
org.apache.juneau.common.utils.CollectionUtils.*;
 import static org.apache.juneau.common.utils.ThrowableUtils.*;
 import static org.apache.juneau.common.utils.Utils.*;
 import static org.apache.juneau.common.reflect.AnnotationTraversal.*;
+import static org.apache.juneau.common.collections.CacheMode.*;
 import static java.util.stream.Stream.*;
 
 import java.lang.annotation.*;
@@ -180,10 +181,55 @@ import org.apache.juneau.common.collections.*;
  */
 public class AnnotationProvider {
 
+       
//-----------------------------------------------------------------------------------------------------------------
+       // System properties
+       
//-----------------------------------------------------------------------------------------------------------------
+
        /**
-        * Disable annotation caching.
+        * Caching mode for annotation lookups.
+        *
+        * <p>
+        * System property: <c>juneau.annotationProvider.caching</c>
+        * <br>Valid values: <c>NONE</c>, <c>WEAK</c>, <c>FULL</c> 
(case-insensitive)
+        * <br>Default: <c>FULL</c>
+        *
+        * <ul>
+        *      <li><c>NONE</c> - Disables all caching (always recompute)
+        *      <li><c>WEAK</c> - Uses WeakHashMap (allows GC of cached entries)
+        *      <li><c>FULL</c> - Uses ConcurrentHashMap (best performance)
+        * </ul>
         */
-       private static final boolean DISABLE_ANNOTATION_CACHING = 
Boolean.getBoolean("juneau.disableAnnotationCaching");
+       private static final CacheMode CACHING_MODE = 
CacheMode.parse(System.getProperty("juneau.annotationProvider.caching", 
"FULL"));
+
+       /**
+        * Enable logging of cache statistics on JVM shutdown.
+        *
+        * <p>
+        * System property: <c>juneau.annotationProvider.caching.logOnExit</c>
+        * <br>Valid values: <c>TRUE</c>, <c>FALSE</c> (case-insensitive)
+        * <br>Default: <c>FALSE</c>
+        */
+       private static final boolean LOG_ON_EXIT = 
b(System.getProperty("juneau.annotationProvider.caching.logOnExit"));
+
+       /**
+        * Enable performance instrumentation for tracking method call counts.
+        *
+        * <p>
+        * System property: <c>juneau.annotationProvider.instrumentation</c>
+        * <br>Valid values: <c>TRUE</c>, <c>FALSE</c> (case-insensitive)
+        * <br>Default: <c>FALSE</c>
+        */
+       private static final boolean ENABLE_INSTRUMENTATION = 
b(System.getProperty("juneau.annotationProvider.instrumentation"));
+
+       /**
+        * Enable new optimized code path for annotation lookups.
+        *
+        * <p>
+        * System property: <c>juneau.annotationProvider.useNewCode</c>
+        * <br>Valid values: <c>TRUE</c>, <c>FALSE</c> (case-insensitive)
+        * <br>Default: <c>FALSE</c>
+        */
+       private static final boolean ENABLE_NEW_CODE = 
b(System.getProperty("juneau.annotationProvider.useNewCode"));
 
        /**
         * Default instance.
@@ -195,9 +241,6 @@ public class AnnotationProvider {
        
//-----------------------------------------------------------------------------------------------------------------
 
        private static final Map<String, Long> methodCallCounts = new 
java.util.concurrent.ConcurrentHashMap<>();
-       private static final boolean ENABLE_INSTRUMENTATION = 
Boolean.getBoolean("juneau.instrumentAnnotationProvider");
-//     private static final boolean ENABLE_NEW_CODE = 
Boolean.getBoolean("juneau.annotationProvider.enableNewCode");
-       private static final boolean ENABLE_NEW_CODE = true;
 
        static {
                if (ENABLE_INSTRUMENTATION) {
@@ -252,11 +295,13 @@ public class AnnotationProvider {
         * </ul>
         */
        public static class Builder {
-               boolean disableCaching;
+               CacheMode cacheMode;
+               boolean logOnExit;
                ReflectionMap.Builder<Annotation> runtimeAnnotations = 
ReflectionMap.create(Annotation.class);
 
                Builder() {
-                       disableCaching = DISABLE_ANNOTATION_CACHING;
+                       cacheMode = CACHING_MODE;
+                       logOnExit = LOG_ON_EXIT;
                }
 
                /**
@@ -269,26 +314,42 @@ public class AnnotationProvider {
                }
 
                /**
-                * Disables annotation caching entirely.
+                * Sets the caching mode for annotation lookups.
                 *
                 * <p>
-                * When disabled, annotation lookups will always perform fresh 
searches without caching results.
+                * Available modes:
+                * <ul>
+                *      <li><c>NONE</c> - Disables all caching (always 
recompute)
+                *      <li><c>WEAK</c> - Uses WeakHashMap (allows GC of cached 
entries)
+                *      <li><c>FULL</c> - Uses ConcurrentHashMap (best 
performance)
+                * </ul>
+                *
+                * @param value The caching mode.
+                * @return This object for method chaining.
+                */
+               public Builder cacheMode(CacheMode value) {
+                       cacheMode = value;
+                       return this;
+               }
+
+               /**
+                * Enables logging of cache statistics on JVM shutdown.
                 *
                 * @return This object for method chaining.
                 */
-               public Builder disableCaching() {
-                       disableCaching = true;
+               public Builder logOnExit() {
+                       logOnExit = true;
                        return this;
                }
 
                /**
-                * Conditionally disables or enables annotation caching.
+                * Conditionally enables logging of cache statistics on JVM 
shutdown.
                 *
-                * @param value Whether to disable caching.
+                * @param value Whether to log on exit.
                 * @return This object for method chaining.
                 */
-               public Builder disableCaching(boolean value) {
-                       disableCaching = value;
+               public Builder logOnExit(boolean value) {
+                       logOnExit = value;
                        return this;
                }
 
@@ -352,11 +413,11 @@ public class AnnotationProvider {
         *              .value(MySwap.<jk>class</jk>)
         *              .build();
         *
- *     <jc>// Add all runtime annotations to the provider</jc>
- *     AnnotationProvider <jv>provider</jv> = AnnotationProvider
- *             .<jsm>create</jsm>()
- *             .addRuntimeAnnotations(<jv>beanAnnotation</jv>, 
<jv>multiAnnotation</jv>, <jv>stringAnnotation</jv>, <jv>swapAnnotation</jv>)
- *             .build();
+        *      <jc>// Add all runtime annotations to the provider</jc>
+        *      AnnotationProvider <jv>provider</jv> = AnnotationProvider
+        *              .<jsm>create</jsm>()
+        *              .addRuntimeAnnotations(<jv>beanAnnotation</jv>, 
<jv>multiAnnotation</jv>, <jv>stringAnnotation</jv>, <jv>swapAnnotation</jv>)
+        *              .build();
         * </p>
         *
         * <p>
@@ -456,26 +517,41 @@ public class AnnotationProvider {
         * @param builder The builder containing configuration settings.
         */
        protected AnnotationProvider(Builder builder) {
-               this.classRuntimeAnnotations = 
Cache.<Class<?>,List<AnnotationInfo<Annotation>>>create()
+               var classCache = 
Cache.<Class<?>,List<AnnotationInfo<Annotation>>>create()
                        .supplier(this::findClassRuntimeAnnotations)
-                       .disableCaching(builder.disableCaching)
-                       .build();
-               this.methodRuntimeAnnotations = 
Cache.<Method,List<AnnotationInfo<Annotation>>>create()
+                       .cacheMode(builder.cacheMode);
+               if (builder.logOnExit)
+                       
classCache.logOnExit("AnnotationProvider.classRuntimeAnnotations");
+               this.classRuntimeAnnotations = classCache.build();
+
+               var methodCache = 
Cache.<Method,List<AnnotationInfo<Annotation>>>create()
                        .supplier(this::findMethodRuntimeAnnotations)
-                       .disableCaching(builder.disableCaching)
-                       .build();
-               this.fieldRuntimeAnnotations = 
Cache.<Field,List<AnnotationInfo<Annotation>>>create()
+                       .cacheMode(builder.cacheMode);
+               if (builder.logOnExit)
+                       
methodCache.logOnExit("AnnotationProvider.methodRuntimeAnnotations");
+               this.methodRuntimeAnnotations = methodCache.build();
+
+               var fieldCache = 
Cache.<Field,List<AnnotationInfo<Annotation>>>create()
                        .supplier(this::findFieldRuntimeAnnotations)
-                       .disableCaching(builder.disableCaching)
-                       .build();
-               this.constructorRuntimeAnnotations = 
Cache.<Constructor<?>,List<AnnotationInfo<Annotation>>>create()
+                       .cacheMode(builder.cacheMode);
+               if (builder.logOnExit)
+                       
fieldCache.logOnExit("AnnotationProvider.fieldRuntimeAnnotations");
+               this.fieldRuntimeAnnotations = fieldCache.build();
+
+               var constructorCache = 
Cache.<Constructor<?>,List<AnnotationInfo<Annotation>>>create()
                        .supplier(this::findConstructorRuntimeAnnotations)
-                       .disableCaching(builder.disableCaching)
-                       .build();
-               this.cache = 
Cache3.<Class<?>,ElementInfo,AnnotationTraversal[],List>create()
+                       .cacheMode(builder.cacheMode);
+               if (builder.logOnExit)
+                       
constructorCache.logOnExit("AnnotationProvider.constructorRuntimeAnnotations");
+               this.constructorRuntimeAnnotations = constructorCache.build();
+
+               var cache3 = 
Cache3.<Class<?>,ElementInfo,AnnotationTraversal[],List>create()
                        .supplier(this::findCached)
-                       .disableCaching(builder.disableCaching)
-                       .build();
+                       .cacheMode(builder.cacheMode);
+               if (builder.logOnExit)
+                       cache3.logOnExit("AnnotationProvider.cache");
+               this.cache = cache3.build();
+
                this.annotationMap = builder.runtimeAnnotations.build();
        }
 
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/MimeTypeDetector.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/MimeTypeDetector.java
index e10de92b86..478b3783cc 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/MimeTypeDetector.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/MimeTypeDetector.java
@@ -16,6 +16,7 @@
  */
 package org.apache.juneau.common.utils;
 
+import static org.apache.juneau.common.collections.CacheMode.*;
 import static org.apache.juneau.common.utils.AssertionUtils.*;
 import static org.apache.juneau.common.utils.FileUtils.*;
 import static org.apache.juneau.common.utils.Utils.*;
@@ -75,7 +76,7 @@ public class MimeTypeDetector {
                private final Map<String,String> fileMap = new 
ConcurrentHashMap<>();
                private boolean nioContentBasedDetection = true;
                private int cacheSize = 1000;
-               private boolean cacheDisabled = false;
+               private CacheMode cacheMode = FULL;
                private boolean cacheLogOnExit = false;
                private String defaultType = "application/octet-stream";
 
@@ -132,13 +133,21 @@ public class MimeTypeDetector {
                }
 
                /**
-                * Enables or disables the cache.
+                * Sets the caching mode for MIME type lookups.
                 *
-                * @param value Whether to disable the cache.
+                * <p>
+                * Available modes:
+                * <ul>
+                *      <li>{@link CacheMode#NONE NONE} - No caching (always 
recompute)
+                *      <li>{@link CacheMode#WEAK WEAK} - Weak caching (uses 
{@link java.util.WeakHashMap})
+                *      <li>{@link CacheMode#FULL FULL} - Full caching (uses 
{@link java.util.concurrent.ConcurrentHashMap}, default)
+                * </ul>
+                *
+                * @param value The caching mode.
                 * @return This builder.
                 */
-               public Builder setCacheDisabled(boolean value) {
-                       cacheDisabled = value;
+               public Builder setCacheMode(CacheMode value) {
+                       cacheMode = value;
                        return this;
                }
 
@@ -257,11 +266,10 @@ public class MimeTypeDetector {
                this.defaultType = builder.defaultType;
 
                // Create cache for file-based lookups
-               var cacheBuilder = Cache.of(String.class, 
String.class).maxSize(builder.cacheSize);
+               var cacheBuilder = Cache.of(String.class, String.class)
+                       .maxSize(builder.cacheSize)
+                       .cacheMode(builder.cacheMode);
 
-               if (builder.cacheDisabled) {
-                       cacheBuilder.disableCaching();
-               }
                if (builder.cacheLogOnExit) {
                        cacheBuilder.logOnExit("MimeTypeDetector");
                }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache2_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache2_Test.java
index 8af66c587c..793a1cb370 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache2_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache2_Test.java
@@ -16,6 +16,8 @@
  */
 package org.apache.juneau.common.collections;
 
+import static org.apache.juneau.common.collections.CacheMode.*;
+
 import static org.junit.jupiter.api.Assertions.*;
 import static org.apache.juneau.junit.bct.BctAssertions.*;
 
@@ -171,7 +173,7 @@ class Cache2_Test extends TestBase {
                var defaultCallCount = new AtomicInteger();
                var overrideCallCount = new AtomicInteger();
                var x = Cache2.of(String.class, Integer.class, String.class)
-                       .disableCaching()
+                       .cacheMode(NONE)
                        .supplier((k1, k2) -> {
                                defaultCallCount.incrementAndGet();
                                return k1 + ":" + k2;
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache3_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache3_Test.java
index 8981e63a14..d34df21009 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache3_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache3_Test.java
@@ -16,6 +16,8 @@
  */
 package org.apache.juneau.common.collections;
 
+import static org.apache.juneau.common.collections.CacheMode.*;
+
 import static org.junit.jupiter.api.Assertions.*;
 import static org.apache.juneau.junit.bct.BctAssertions.*;
 
@@ -75,7 +77,7 @@ class Cache3_Test extends TestBase {
        void a04_disableCaching() {
                var callCount = new AtomicInteger();
                var x = Cache3.of(String.class, String.class, Integer.class, 
String.class)
-                       .disableCaching()
+                       .cacheMode(NONE)
                        .supplier((k1, k2, k3) -> {
                                callCount.incrementAndGet();
                                return "value";
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache4_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache4_Test.java
index 59dd58254e..41005643fe 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache4_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache4_Test.java
@@ -16,6 +16,8 @@
  */
 package org.apache.juneau.common.collections;
 
+import static org.apache.juneau.common.collections.CacheMode.*;
+
 import static org.junit.jupiter.api.Assertions.*;
 import static org.apache.juneau.junit.bct.BctAssertions.*;
 
@@ -76,7 +78,7 @@ class Cache4_Test extends TestBase {
        void a04_disableCaching() {
                var callCount = new AtomicInteger();
                var x = Cache4.of(String.class, String.class, String.class, 
Integer.class, String.class)
-                       .disableCaching()
+                       .cacheMode(NONE)
                        .supplier((k1, k2, k3, k4) -> {
                                callCount.incrementAndGet();
                                return "value";
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache5_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache5_Test.java
index 0075a83093..696ea8df47 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache5_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache5_Test.java
@@ -16,6 +16,8 @@
  */
 package org.apache.juneau.common.collections;
 
+import static org.apache.juneau.common.collections.CacheMode.*;
+
 import static org.junit.jupiter.api.Assertions.*;
 import static org.apache.juneau.junit.bct.BctAssertions.*;
 
@@ -77,7 +79,7 @@ class Cache5_Test extends TestBase {
        void a04_disableCaching() {
                var callCount = new AtomicInteger();
                var x = Cache5.of(String.class, String.class, String.class, 
String.class, Integer.class, String.class)
-                       .disableCaching()
+                       .cacheMode(NONE)
                        .supplier((k1, k2, k3, k4, k5) -> {
                                callCount.incrementAndGet();
                                return "value";
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache_Test.java
index 4954cca8c4..954858ce09 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/common/collections/Cache_Test.java
@@ -16,6 +16,8 @@
  */
 package org.apache.juneau.common.collections;
 
+import static org.apache.juneau.common.collections.CacheMode.*;
+
 import static org.apache.juneau.junit.bct.BctAssertions.*;
 import static org.junit.jupiter.api.Assertions.*;
 
@@ -199,7 +201,7 @@ class Cache_Test extends TestBase {
 
        @Test void a10_disabled_neverCaches() {
                var cache = Cache.of(String.class, String.class)
-                       .disableCaching()
+                       .cacheMode(NONE)
                        .build();
                var callCount = new AtomicInteger();
 
@@ -222,7 +224,7 @@ class Cache_Test extends TestBase {
 
        @Test void a11_disabled_sizeAlwaysZero() {
                var cache = Cache.of(String.class, Integer.class)
-                       .disableCaching()
+                       .cacheMode(NONE)
                        .build();
 
                cache.get("one", () -> 1);
@@ -234,7 +236,7 @@ class Cache_Test extends TestBase {
 
        @Test void a12_disabled_clearHasNoEffect() {
                var cache = Cache.of(String.class, Integer.class)
-                       .disableCaching()
+                       .cacheMode(NONE)
                        .build();
 
                cache.clear(); // Should not throw
@@ -256,7 +258,7 @@ class Cache_Test extends TestBase {
        @Test void a14_builder_chaining() {
                var cache = Cache.of(String.class, String.class)
                        .maxSize(100)
-                       .disableCaching()
+                       .cacheMode(NONE)
                        .build();
 
                // Disabled takes precedence
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/common/utils/MimeTypeDetector_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/common/utils/MimeTypeDetector_Test.java
index 5866d5a2d1..cfd6a491ad 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/common/utils/MimeTypeDetector_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/common/utils/MimeTypeDetector_Test.java
@@ -21,6 +21,7 @@ import static org.junit.jupiter.api.Assertions.*;
 import java.io.*;
 import java.nio.file.*;
 
+import org.apache.juneau.common.collections.*;
 import org.junit.jupiter.api.*;
 import org.junit.jupiter.api.io.*;
 
@@ -142,7 +143,7 @@ public class MimeTypeDetector_Test {
        @Test
        public void testSetCacheDisabled() {
                var detector = MimeTypeDetector.builder()
-                       .setCacheDisabled(true)
+                       .setCacheMode(CacheMode.NONE)
                        .addExtensionType("test", "application/x-test")
                        .build();
                
@@ -371,7 +372,7 @@ public class MimeTypeDetector_Test {
        @Test
        public void testCacheDisabled() {
                var detector = MimeTypeDetector.builder()
-                       .setCacheDisabled(true)
+                       .setCacheMode(CacheMode.NONE)
                        .addExtensionType("test", "application/x-test")
                        .build();
                
@@ -405,7 +406,7 @@ public class MimeTypeDetector_Test {
                        .addExtensionType("custom", "application/x-custom")
                        .addNioContentBasedDetection(false)
                        .setCacheSize(100)
-                       .setCacheDisabled(false)
+                       .setCacheMode(CacheMode.FULL)
                        .setCacheLogOnExit(true)
                        .setDefaultType("application/unknown")
                        .addTypes("text/html html htm")

Reply via email to