diff --git a/caffeine/build.gradle.kts b/caffeine/build.gradle.kts
index 55ef7c0432..05053dc8db 100644
--- a/caffeine/build.gradle.kts
+++ b/caffeine/build.gradle.kts
@@ -256,6 +256,7 @@ tasks.register<JavaExec>("memoryOverhead") {
 tasks.register<Stress>("stress") {
   group = "Cache tests"
   description = "Executes a stress test"
+  mainClass = "com.github.benmanes.caffeine.cache.Stresser"
   classpath = sourceSets["codeGen"].runtimeClasspath + sourceSets["test"].runtimeClasspath
   outputs.upToDateWhen { false }
   dependsOn(tasks.compileTestJava)
@@ -313,23 +314,18 @@ idea.module {
   scopes["PROVIDED"]!!["plus"]!!.add(configurations["javaPoetCompileClasspath"])
 }
 
-abstract class Stress @Inject constructor(@Internal val external: ExecOperations) : DefaultTask() {
-  @get:Input @get:Optional @get:Option(option = "workload", description = "The workload type")
-  abstract val operation: Property<String>
-  @get:InputFiles @get:Classpath
-  abstract val classpath: Property<FileCollection>
+abstract class Stress : JavaExec() {
+  @Input @Option(option = "workload", description = "The workload type")
+  var operation: String = ""
 
   @TaskAction
-  fun run() {
-    external.javaexec {
-      mainClass = "com.github.benmanes.caffeine.cache.Stresser"
-      classpath(this@Stress.classpath)
-      if (operation.isPresent) {
-        args("--workload", operation.get())
-      } else {
-        args("--help")
-      }
+  override fun exec() {
+    if (operation.isNotEmpty()) {
+      args("--workload", operation)
+    } else {
+      args("--help")
     }
+    super.exec()
   }
 }
 
diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsMapTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsMapTest.java
index c993cd1987..c88bb28693 100644
--- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsMapTest.java
+++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsMapTest.java
@@ -1881,7 +1881,7 @@ public void keySet_removeAll_self(Map<Int, Int> map, CacheContext context) {
   @CacheSpec(population = Population.FULL, implementation = Implementation.Caffeine)
   public void keySet_removeAll_byCollection(Map<Int, Int> map, CacheContext context) {
     var delegate = Sets.union(context.original().keySet(), context.absentKeys());
-    var keys = Mockito.mock(Collection.class);
+    Collection<Int> keys = Mockito.mock();
     when(keys.iterator()).thenReturn(delegate.iterator());
 
     assertThat(map.keySet().removeAll(keys)).isTrue();
@@ -1894,10 +1894,9 @@ public void keySet_removeAll_byCollection(Map<Int, Int> map, CacheContext contex
   @CacheSpec(population = Population.FULL, implementation = Implementation.Caffeine)
   public void keySet_removeAll_bySet(Map<Int, Int> map, CacheContext context) {
     var delegate = Sets.union(context.original().keySet(), context.absentKeys());
-    var keys = Mockito.mock(Set.class);
+    Set<Int> keys = Mockito.mock();
     when(keys.size()).thenReturn(delegate.size());
-    when(keys.contains(any())).thenAnswer(invocation ->
-        delegate.contains(invocation.getArgument(0)));
+    when(keys.contains(any())).then(invocation -> delegate.contains(invocation.getArgument(0)));
 
     assertThat(map.keySet().removeAll(keys)).isTrue();
     verify(keys).size();
@@ -2726,7 +2725,7 @@ public void entrySet_removeAll_self(Map<Int, Int> map, CacheContext context) {
   @CacheSpec(population = Population.FULL, implementation = Implementation.Caffeine)
   public void entrySet_removeAll_byCollection(Map<Int, Int> map, CacheContext context) {
     var delegate = Sets.union(context.original().entrySet(), context.absent().entrySet());
-    var entries = Mockito.mock(Collection.class);
+    Collection<Map.Entry<Int, Int>> entries = Mockito.mock();
     when(entries.iterator()).thenReturn(delegate.iterator());
 
     assertThat(map.entrySet().removeAll(entries)).isTrue();
@@ -2739,10 +2738,9 @@ public void entrySet_removeAll_byCollection(Map<Int, Int> map, CacheContext cont
   @CacheSpec(population = Population.FULL, implementation = Implementation.Caffeine)
   public void entrySet_removeAll_bySet(Map<Int, Int> map, CacheContext context) {
     var delegate = Sets.union(context.original().entrySet(), context.absent().entrySet());
-    var entries = Mockito.mock(Set.class);
+    Set<Map.Entry<Int, Int>> entries = Mockito.mock();
     when(entries.size()).thenReturn(delegate.size());
-    when(entries.contains(any())).thenAnswer(invocation ->
-        delegate.contains(invocation.getArgument(0)));
+    when(entries.contains(any())).then(invocation -> delegate.contains(invocation.getArgument(0)));
 
     assertThat(map.entrySet().removeAll(entries)).isTrue();
     verify(entries).size();
diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncAsMapTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncAsMapTest.java
index fb66a1d3da..b423c5ac1d 100644
--- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncAsMapTest.java
+++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncAsMapTest.java
@@ -1599,7 +1599,7 @@ public void keySet_removeAll_self(AsyncCache<Int, Int> cache, CacheContext conte
   @CacheSpec(population = Population.FULL, implementation = Implementation.Caffeine)
   public void keySet_removeAll_byCollection(AsyncCache<Int, Int> cache, CacheContext context) {
     var delegate = Sets.union(context.original().keySet(), context.absentKeys());
-    var keys = Mockito.mock(Collection.class);
+    Collection<Int> keys = Mockito.mock();
     when(keys.iterator()).thenReturn(delegate.iterator());
 
     assertThat(cache.asMap().keySet().removeAll(keys)).isTrue();
@@ -1612,10 +1612,9 @@ public void keySet_removeAll_byCollection(AsyncCache<Int, Int> cache, CacheConte
   @CacheSpec(population = Population.FULL, implementation = Implementation.Caffeine)
   public void keySet_removeAll_bySet(AsyncCache<Int, Int> cache, CacheContext context) {
     var delegate = Sets.union(context.original().keySet(), context.absentKeys());
-    var keys = Mockito.mock(Set.class);
+    Set<Int> keys = Mockito.mock();
     when(keys.size()).thenReturn(delegate.size());
-    when(keys.contains(any())).thenAnswer(invocation ->
-        delegate.contains(invocation.getArgument(0)));
+    when(keys.contains(any())).then(invocation -> delegate.contains(invocation.getArgument(0)));
 
     assertThat(cache.asMap().keySet().removeAll(keys)).isTrue();
     verify(keys).size();
@@ -2480,7 +2479,7 @@ public void entrySet_removeAll_self(AsyncCache<Int, Int> cache, CacheContext con
   public void entrySet_removeAll_byCollection(AsyncCache<Int, Int> cache, CacheContext context) {
     var delegate = Sets.union(cache.asMap().entrySet(),
         Maps.transformValues(context.absent(), Int::asFuture).entrySet());
-    var entries = Mockito.mock(Collection.class);
+    Collection<Map.Entry<Int, CompletableFuture<Int>>> entries = Mockito.mock();
     when(entries.iterator()).thenReturn(delegate.iterator());
 
     assertThat(cache.asMap().entrySet().removeAll(entries)).isTrue();
@@ -2494,10 +2493,9 @@ public void entrySet_removeAll_byCollection(AsyncCache<Int, Int> cache, CacheCon
   public void entrySet_removeAll_bySet(AsyncCache<Int, Int> cache, CacheContext context) {
     var delegate = Sets.union(cache.asMap().entrySet(),
         Maps.transformValues(context.absent(), Int::asFuture).entrySet());
-    var entries = Mockito.mock(Set.class);
+    Set<Map.Entry<Int, CompletableFuture<Int>>> entries = Mockito.mock();
     when(entries.size()).thenReturn(delegate.size());
-    when(entries.contains(any())).thenAnswer(invocation ->
-        delegate.contains(invocation.getArgument(0)));
+    when(entries.contains(any())).then(invocation -> delegate.contains(invocation.getArgument(0)));
 
     assertThat(cache.asMap().entrySet().removeAll(entries)).isTrue();
     verify(entries).size();
diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/BoundedLocalCacheTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/BoundedLocalCacheTest.java
index 60f3e7e595..d8acd49509 100644
--- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/BoundedLocalCacheTest.java
+++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/BoundedLocalCacheTest.java
@@ -56,7 +56,6 @@
 import static org.mockito.Mockito.CALLS_REAL_METHODS;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doCallRealMethod;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
@@ -251,7 +250,7 @@ public void cleanupTask_allowGc() {
   @CheckMaxLogLevel(ERROR)
   public void cleanupTask_exception() {
     var expected = new RuntimeException();
-    var cache = Mockito.mock(BoundedLocalCache.class);
+    BoundedLocalCache<?, ?> cache = Mockito.mock();
     doThrow(expected).when(cache).performCleanUp(any());
     var task = new PerformCleanupTask(cache);
     assertThat(task.exec()).isFalse();
@@ -267,7 +266,7 @@ public void cleanupTask_exception() {
   @CheckMaxLogLevel(ERROR)
   public void cleanup_exception() {
     var expected = new RuntimeException();
-    var cache = Mockito.mock(BoundedLocalCache.class);
+    BoundedLocalCache<?, ?> cache = Mockito.mock();
     doThrow(expected).when(cache).performCleanUp(any());
     doCallRealMethod().when(cache).cleanUp();
     cache.cleanUp();
@@ -312,7 +311,7 @@ public void scheduleAfterWrite_invalidDrainStatus() {
 
   @Test
   public void scheduleDrainBuffers() {
-    var executor = Mockito.mock(Executor.class);
+    Executor executor = Mockito.mock();
     var cache = new BoundedLocalCache<Object, Object>(
         Caffeine.newBuilder().executor(executor), /* loader */ null, /* async */ false) {};
     var transitions = Map.of(
@@ -2006,8 +2005,8 @@ public void putIfAbsent_expireAfterRead(BoundedLocalCache<Int, Int> cache, Cache
       expireAfterAccess = {Expire.DISABLED, Expire.ONE_MINUTE},
       expireAfterWrite = {Expire.DISABLED, Expire.ONE_MINUTE})
   public void unschedule_cleanUp(BoundedLocalCache<Int, Int> cache, CacheContext context) {
-    var future = Mockito.mock(Future.class);
-    doReturn(future).when(context.scheduler()).schedule(any(), any(), anyLong(), any());
+    Future<?> future = Mockito.mock();
+    when(context.scheduler().schedule(any(), any(), anyLong(), any())).then(invocation -> future);
 
     for (int i = 0; i < 10; i++) {
       var value = cache.put(Int.valueOf(i), Int.valueOf(-i));
@@ -2032,8 +2031,8 @@ public void unschedule_cleanUp(BoundedLocalCache<Int, Int> cache, CacheContext c
       expireAfterAccess = {Expire.DISABLED, Expire.ONE_MINUTE},
       expireAfterWrite = {Expire.DISABLED, Expire.ONE_MINUTE})
   public void unschedule_invalidateAll(BoundedLocalCache<Int, Int> cache, CacheContext context) {
-    var future = Mockito.mock(Future.class);
-    doReturn(future).when(context.scheduler()).schedule(any(), any(), anyLong(), any());
+    Future<?> future = Mockito.mock();
+    when(context.scheduler().schedule(any(), any(), anyLong(), any())).then(invocation -> future);
 
     for (int i = 0; i < 10; i++) {
       var value = cache.put(Int.valueOf(i), Int.valueOf(-i));
@@ -2200,7 +2199,7 @@ public void expirationDelay_varTime(BoundedLocalCache<Int, Int> cache, CacheCont
       refreshAfterWrite = Expire.ONE_MINUTE, executor = CacheExecutor.THREADED,
       compute = Compute.SYNC, stats = Stats.DISABLED)
   public void refreshIfNeeded_liveliness(CacheContext context) {
-    var stats = Mockito.mock(StatsCounter.class);
+    StatsCounter stats = Mockito.mock();
     context.caffeine().recordStats(() -> stats);
 
     // Capture the refresh parameters, should not be retired/dead sentinel entry
@@ -2300,13 +2299,13 @@ public CompletableFuture<Int> asyncReload(Int key, Int oldValue, Executor execut
   @CacheSpec(population = Population.EMPTY, executor = CacheExecutor.THREADED,
       compute = Compute.ASYNC, stats = Stats.DISABLED)
   public void refresh_startReloadBeforeLoadCompletion(CacheContext context) {
-    var stats = Mockito.mock(StatsCounter.class);
     var beganLoadSuccess = new AtomicBoolean();
     var endLoadSuccess = new CountDownLatch(1);
     var beganReloading = new AtomicBoolean();
     var beganLoading = new AtomicBoolean();
     var endReloading = new AtomicBoolean();
     var endLoading = new AtomicBoolean();
+    StatsCounter stats = Mockito.mock();
 
     context.ticker().setAutoIncrementStep(Duration.ofSeconds(1));
     context.caffeine().recordStats(() -> stats);
diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ExpirationTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ExpirationTest.java
index 16b2977189..779ef3c31a 100644
--- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ExpirationTest.java
+++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ExpirationTest.java
@@ -35,7 +35,6 @@
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -142,8 +141,8 @@ public void expire_evictionListener_failure(Cache<Int, Int> cache, CacheContext
   public void schedule(Cache<Int, Int> cache, CacheContext context) {
     var delay = ArgumentCaptor.forClass(long.class);
     var task = ArgumentCaptor.forClass(Runnable.class);
-    doReturn(DisabledFuture.INSTANCE).when(context.scheduler()).schedule(
-        eq(context.executor()), task.capture(), delay.capture(), eq(TimeUnit.NANOSECONDS));
+    when(context.scheduler().schedule(eq(context.executor()), task.capture(), delay.capture(),
+        eq(TimeUnit.NANOSECONDS))).then(invocation -> DisabledFuture.INSTANCE);
 
     cache.put(context.absentKey(), context.absentValue());
 
@@ -172,10 +171,10 @@ public void schedule(Cache<Int, Int> cache, CacheContext context) {
       expireAfterAccess = {Expire.DISABLED, Expire.ONE_MINUTE}, expiryTime = Expire.ONE_MINUTE,
       expireAfterWrite = {Expire.DISABLED, Expire.ONE_MINUTE})
   public void schedule_immediate(Cache<Int, Int> cache, CacheContext context) {
-    doAnswer(invocation -> {
+    when(context.scheduler().schedule(any(), any(), anyLong(), any())).then(invocation -> {
       invocation.<Runnable>getArgument(1).run();
       return new CompletableFuture<>();
-    }).when(context.scheduler()).schedule(any(), any(), anyLong(), any());
+    });
 
     cache.put(context.absentKey(), context.absentValue());
     verify(context.scheduler()).schedule(any(), any(), anyLong(), any());
diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/PacerTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/PacerTest.java
index e8bfef4166..550f1e0f40 100644
--- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/PacerTest.java
+++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/PacerTest.java
@@ -16,11 +16,10 @@
 package com.github.benmanes.caffeine.cache;
 
 import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
 
 import java.util.Random;
 import java.util.concurrent.CompletableFuture;
@@ -60,8 +59,8 @@ public void beforeMethod() throws Exception {
   @Test
   public void schedule_initialize() {
     long delay = random.nextInt(Ints.saturatedCast(Pacer.TOLERANCE));
-    doReturn(future)
-        .when(scheduler).schedule(executor, command, Pacer.TOLERANCE, TimeUnit.NANOSECONDS);
+    when(scheduler.schedule(executor, command, Pacer.TOLERANCE, TimeUnit.NANOSECONDS))
+        .then(invocation -> future);
     pacer.schedule(executor, command, NOW, delay);
 
     assertThat(pacer.isScheduled()).isTrue();
@@ -72,12 +71,13 @@ public void schedule_initialize() {
   @Test
   public void schedule_initialize_recurse() {
     long delay = random.nextInt(Ints.saturatedCast(Pacer.TOLERANCE));
-    doAnswer(invocation -> {
-      assertThat(pacer.future).isNull();
-      assertThat(pacer.nextFireTime).isNotEqualTo(0);
-      pacer.schedule(executor, command, NOW, delay);
-      return future;
-    }).when(scheduler).schedule(executor, command, Pacer.TOLERANCE, TimeUnit.NANOSECONDS);
+    when(scheduler.schedule(executor, command, Pacer.TOLERANCE, TimeUnit.NANOSECONDS))
+        .then(invocation -> {
+          assertThat(pacer.future).isNull();
+          assertThat(pacer.nextFireTime).isNotEqualTo(0);
+          pacer.schedule(executor, command, NOW, delay);
+          return future;
+        });
 
     pacer.schedule(executor, command, NOW, delay);
 
@@ -90,8 +90,8 @@ public void schedule_initialize_recurse() {
   public void schedule_cancel_schedule() {
     long fireTime = NOW + Pacer.TOLERANCE;
     long delay = random.nextInt(Ints.saturatedCast(Pacer.TOLERANCE));
-    doReturn(future)
-        .when(scheduler).schedule(executor, command, Pacer.TOLERANCE, TimeUnit.NANOSECONDS);
+    when(scheduler.schedule(executor, command, Pacer.TOLERANCE, TimeUnit.NANOSECONDS))
+        .then(invocation -> future);
 
     pacer.schedule(executor, command, NOW, delay);
     assertThat(pacer.nextFireTime).isEqualTo(fireTime);
@@ -146,8 +146,8 @@ public void schedule_beforeNextFireTime_minimumDelay() {
     pacer.future = future;
 
     long delay = random.nextInt(Ints.saturatedCast(Pacer.TOLERANCE));
-    doReturn(future)
-        .when(scheduler).schedule(executor, command, Pacer.TOLERANCE, TimeUnit.NANOSECONDS);
+    when(scheduler.schedule(executor, command, Pacer.TOLERANCE, TimeUnit.NANOSECONDS))
+        .then(invocation -> future);
     pacer.schedule(executor, command, NOW, delay);
 
     verify(future).cancel(false);
@@ -167,8 +167,8 @@ public void schedule_beforeNextFireTime_customDelay() {
     pacer.future = future;
 
     long delay = (Pacer.TOLERANCE + Math.max(1, random.nextInt()));
-    doReturn(future)
-        .when(scheduler).schedule(executor, command, delay, TimeUnit.NANOSECONDS);
+    when(scheduler.schedule(executor, command, delay, TimeUnit.NANOSECONDS))
+        .then(invocation -> future);
     pacer.schedule(executor, command, NOW, delay);
 
     verify(future).cancel(false);
diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/SchedulerTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/SchedulerTest.java
index 58fa2945cf..a6389d2b8c 100644
--- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/SchedulerTest.java
+++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/SchedulerTest.java
@@ -129,9 +129,9 @@ public void guardedScheduler_null() {
 
   @Test
   public void guardedScheduler_nullFuture() {
-    var scheduledExecutor = Mockito.mock(ScheduledExecutorService.class);
+    ScheduledExecutorService scheduledExecutor = Mockito.mock();
     var scheduler = Scheduler.forScheduledExecutorService(scheduledExecutor);
-    var executor = Mockito.mock(Executor.class);
+    Executor executor = Mockito.mock();
     Runnable command = () -> {};
 
     var future = Scheduler.guardedScheduler(scheduler)
@@ -169,9 +169,9 @@ public void scheduledExecutorService_null() {
 
   @Test
   public void scheduledExecutorService_schedule() {
-    var scheduledExecutor = Mockito.mock(ScheduledExecutorService.class);
+    ScheduledExecutorService scheduledExecutor = Mockito.mock();
     var task = ArgumentCaptor.forClass(Runnable.class);
-    var executor = Mockito.mock(Executor.class);
+    Executor executor = Mockito.mock();
     Runnable command = () -> {};
 
     var scheduler = Scheduler.forScheduledExecutorService(scheduledExecutor);
@@ -189,8 +189,8 @@ public void scheduledExecutorService_schedule() {
 
   @Test
   public void scheduledExecutorService_shutdown() {
-    var scheduledExecutor = Mockito.mock(ScheduledExecutorService.class);
-    var executor = Mockito.mock(Executor.class);
+    ScheduledExecutorService scheduledExecutor = Mockito.mock();
+    Executor executor = Mockito.mock();
 
     when(scheduledExecutor.isShutdown()).thenReturn(true);
     var scheduler = Scheduler.forScheduledExecutorService(scheduledExecutor);
diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/TimerWheelTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/TimerWheelTest.java
index 01c5476ac0..8029ad2e96 100644
--- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/TimerWheelTest.java
+++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/TimerWheelTest.java
@@ -402,7 +402,7 @@ public void deschedule_fuzzy(long clock, long nanos, long[] times) {
 
   @Test(dataProvider = "clock")
   public void expire_reschedule(long clock) {
-    when(cache.evictEntry(captor.capture(), any(), anyLong())).thenAnswer(invocation -> {
+    when(cache.evictEntry(captor.capture(), any(), anyLong())).then(invocation -> {
       Timer timer = invocation.getArgument(0);
       timer.setVariableTime(timerWheel.nanos + 100);
       return false;
diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/StatsCounterTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/StatsCounterTest.java
index 400ae33970..27d7ca2138 100644
--- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/StatsCounterTest.java
+++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/StatsCounterTest.java
@@ -112,7 +112,7 @@ public void guarded_sameInstance() {
 
   @Test
   public void guarded_exception() {
-    var statsCounter = Mockito.mock(StatsCounter.class);
+    StatsCounter statsCounter = Mockito.mock();
     when(statsCounter.snapshot()).thenThrow(new NullPointerException());
     doThrow(NullPointerException.class).when(statsCounter).recordHits(anyInt());
     doThrow(NullPointerException.class).when(statsCounter).recordMisses(anyInt());
diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheSpec.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheSpec.java
index c0ee3b81fe..8c26b9f6ed 100644
--- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheSpec.java
+++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheSpec.java
@@ -203,7 +203,7 @@ enum CacheWeigher {
     /** A flag indicating that the entry's weight records interactions. */
     @SuppressWarnings("unchecked")
     MOCKITO(() -> {
-      var weigher = Mockito.mock(Weigher.class);
+      Weigher<Object, Object> weigher = Mockito.mock();
       when(weigher.weigh(any(), any())).thenReturn(1);
       return weigher;
     }, 1);
@@ -391,7 +391,7 @@ enum Listener {
     /** A {@link ConsumingRemovalListener} retains all notifications for evaluation by the test. */
     CONSUMING(RemovalListeners::consuming),
     /** A removal listener that records interactions. */
-    MOCKITO(() -> Mockito.mock(RemovalListener.class));
+    MOCKITO(() -> Mockito.mock());
 
     private final Supplier<RemovalListener<Object, Object>> factory;
 
@@ -796,7 +796,7 @@ enum CacheScheduler {
     DISABLED(() -> null),
     SYSTEM(Scheduler::systemScheduler),
     THREADED(() -> Scheduler.forScheduledExecutorService(scheduledExecutor)),
-    MOCKITO(() -> Mockito.mock(Scheduler.class));
+    MOCKITO(() -> Mockito.mock());
 
     private final Supplier<Scheduler> scheduler;
 
diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/lincheck/AbstractLincheckCacheTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/lincheck/AbstractLincheckCacheTest.java
index 2fe7020f3a..ce643b398c 100644
--- a/caffeine/src/test/java/com/github/benmanes/caffeine/lincheck/AbstractLincheckCacheTest.java
+++ b/caffeine/src/test/java/com/github/benmanes/caffeine/lincheck/AbstractLincheckCacheTest.java
@@ -113,11 +113,6 @@ public boolean containsKey(@Param(name = "key") int key) {
     return cache.asMap().containsKey(key);
   }
 
-  @Operation
-  public boolean containsValue(@Param(name = "value") int value) {
-    return cache.asMap().containsValue(value);
-  }
-
   @Operation
   public Integer get_asMap(@Param(name = "key") int key) {
     return cache.asMap().get(key);
@@ -169,7 +164,7 @@ public Integer computeIfPresent(@Param(name = "key") int key,
 
   @Operation
   public Integer compute(@Param(name = "key") int key, @Param(name = "value") int nextValue) {
-    return cache.asMap().compute(key, (k, v) -> nextValue);
+    return cache.asMap().merge(key, nextValue, (oldValue, newValue) -> oldValue + newValue);
   }
 
   @Operation
diff --git a/examples/coalescing-bulkloader-reactor/build.gradle.kts b/examples/coalescing-bulkloader-reactor/build.gradle.kts
index 8f7f075b6a..427799b3d0 100644
--- a/examples/coalescing-bulkloader-reactor/build.gradle.kts
+++ b/examples/coalescing-bulkloader-reactor/build.gradle.kts
@@ -18,7 +18,7 @@ testing.suites {
 }
 
 java.toolchain.languageVersion = JavaLanguageVersion.of(
-  System.getenv("JAVA_VERSION")?.toIntOrNull() ?: 11)
+  System.getenv("JAVA_VERSION")?.toIntOrNull() ?: 21)
 
 tasks.withType<JavaCompile>().configureEach {
   javaCompiler = javaToolchains.compilerFor {
diff --git a/examples/coalescing-bulkloader-reactor/gradle/gradle-daemon-jvm.properties b/examples/coalescing-bulkloader-reactor/gradle/gradle-daemon-jvm.properties
new file mode 100644
index 0000000000..858feb7e38
--- /dev/null
+++ b/examples/coalescing-bulkloader-reactor/gradle/gradle-daemon-jvm.properties
@@ -0,0 +1,2 @@
+#This file is generated by updateDaemonJvm
+toolchainVersion=17
diff --git a/examples/coalescing-bulkloader-reactor/gradle/libs.versions.toml b/examples/coalescing-bulkloader-reactor/gradle/libs.versions.toml
index b286e206eb..0babf4f325 100644
--- a/examples/coalescing-bulkloader-reactor/gradle/libs.versions.toml
+++ b/examples/coalescing-bulkloader-reactor/gradle/libs.versions.toml
@@ -1,6 +1,6 @@
 [versions]
 caffeine = "3.1.8"
-junit = "5.10.2"
+junit = "5.11.0-M1"
 reactor = "3.6.5"
 truth = "1.4.2"
 versions = "0.51.0"
diff --git a/examples/coalescing-bulkloader-reactor/gradle/wrapper/gradle-wrapper.properties b/examples/coalescing-bulkloader-reactor/gradle/wrapper/gradle-wrapper.properties
index 11fbe40fcb..1de365ecd3 100644
--- a/examples/coalescing-bulkloader-reactor/gradle/wrapper/gradle-wrapper.properties
+++ b/examples/coalescing-bulkloader-reactor/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-rc-1-bin.zip
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
diff --git a/examples/coalescing-bulkloader-reactor/settings.gradle.kts b/examples/coalescing-bulkloader-reactor/settings.gradle.kts
index 59f2e287ef..4068e9b011 100644
--- a/examples/coalescing-bulkloader-reactor/settings.gradle.kts
+++ b/examples/coalescing-bulkloader-reactor/settings.gradle.kts
@@ -1,6 +1,6 @@
 plugins {
-  id("com.gradle.develocity") version "3.17.1"
-  id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0"
+  id("com.gradle.develocity") version "3.17.2"
+  id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.1"
   id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
 }
 
diff --git a/examples/graal-native/README.md b/examples/graal-native/README.md
index 71baf42dd8..6ca2491dd4 100644
--- a/examples/graal-native/README.md
+++ b/examples/graal-native/README.md
@@ -3,17 +3,11 @@
 ### Install GraalVM using sdkman.io
 
 ```console
-sdk install java 22.3.2.r17-grl
-sdk use java 22.3.2.r17-grl
+sdk install java 22-graal
+sdk use java 22-graal
 export JAVA_HOME=${SDKMAN_DIR}/candidates/java/current
 ```
 
-### Install native image support
-
-```console
-gu install native-image
-```
-
 ### Run on the JVM with an agent to capture class metadata
 
 ```console
@@ -32,7 +26,7 @@ gradle run -Pagent
 ./gradlew nativeRun
 ```
 
-### Try the binary yourself at
+### Try the binary yourself
 
 ```console
 ./build/native/nativeCompile/graal-native
diff --git a/examples/graal-native/gradle/wrapper/gradle-wrapper.properties b/examples/graal-native/gradle/wrapper/gradle-wrapper.properties
index 11fbe40fcb..1de365ecd3 100644
--- a/examples/graal-native/gradle/wrapper/gradle-wrapper.properties
+++ b/examples/graal-native/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-rc-1-bin.zip
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
diff --git a/examples/graal-native/settings.gradle.kts b/examples/graal-native/settings.gradle.kts
index 8dad06008c..1cff25b1c0 100644
--- a/examples/graal-native/settings.gradle.kts
+++ b/examples/graal-native/settings.gradle.kts
@@ -5,8 +5,8 @@ pluginManagement {
   }
 }
 plugins {
-  id("com.gradle.develocity") version "3.17.1"
-  id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0"
+  id("com.gradle.develocity") version "3.17.2"
+  id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.1"
   id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
 }
 
diff --git a/examples/graal-native/src/main/resources/META-INF/native-image/jni-config.json b/examples/graal-native/src/main/resources/META-INF/native-image/jni-config.json
index b263907f63..74a741548f 100644
--- a/examples/graal-native/src/main/resources/META-INF/native-image/jni-config.json
+++ b/examples/graal-native/src/main/resources/META-INF/native-image/jni-config.json
@@ -5,16 +5,10 @@
 },
 {
   "name":"java.lang.String",
-  "methods":[
-    {"name":"lastIndexOf","parameterTypes":["int"] }, 
-    {"name":"substring","parameterTypes":["int"] }
-  ]
+  "methods":[{"name":"lastIndexOf","parameterTypes":["int"] }, {"name":"substring","parameterTypes":["int"] }]
 },
 {
   "name":"java.lang.System",
-  "methods":[
-    {"name":"getProperty","parameterTypes":["java.lang.String"] }, 
-    {"name":"setProperty","parameterTypes":["java.lang.String","java.lang.String"] }
-  ]
+  "methods":[{"name":"getProperty","parameterTypes":["java.lang.String"] }, {"name":"setProperty","parameterTypes":["java.lang.String","java.lang.String"] }]
 }
 ]
\ No newline at end of file
diff --git a/examples/graal-native/src/main/resources/META-INF/native-image/reflect-config.json b/examples/graal-native/src/main/resources/META-INF/native-image/reflect-config.json
index 58ad650f97..b8fbdaa874 100644
--- a/examples/graal-native/src/main/resources/META-INF/native-image/reflect-config.json
+++ b/examples/graal-native/src/main/resources/META-INF/native-image/reflect-config.json
@@ -29,10 +29,7 @@
 },
 {
   "name":"com.github.benmanes.caffeine.cache.PS",
-  "fields":[
-    {"name":"key"},
-    {"name":"value"}
-  ]
+  "fields":[{"name":"key"}, {"name":"value"}]
 },
 {
   "name":"com.github.benmanes.caffeine.cache.PSMS",
@@ -40,10 +37,25 @@
 },
 {
   "name":"com.github.benmanes.caffeine.cache.SSSMS",
-  "methods":[{"name":"<init>","parameterTypes":["com.github.benmanes.caffeine.cache.Caffeine","com.github.benmanes.caffeine.cache.AsyncCacheLoader","boolean"] }]
+  "fields":[{"name":"FACTORY"}]
 },
 {
   "name":"com.github.benmanes.caffeine.cache.StripedBuffer",
   "fields":[{"name":"tableBusy"}]
+},
+{
+  "name":"java.lang.Thread",
+  "fields":[{"name":"threadLocalRandomProbe"}]
+},
+{
+  "name":"java.util.concurrent.ForkJoinTask",
+  "fields":[{"name":"aux"}, {"name":"status"}]
+},
+{
+  "name":"java.util.concurrent.atomic.Striped64",
+  "fields":[{"name":"base"}, {"name":"cellsBusy"}]
+},
+{
+  "name":"jdk.internal.misc.Unsafe"
 }
-]
+]
\ No newline at end of file
diff --git a/examples/graal-native/src/main/resources/META-INF/native-image/resource-config.json b/examples/graal-native/src/main/resources/META-INF/native-image/resource-config.json
index da9e8da1d4..87cdaffe05 100644
--- a/examples/graal-native/src/main/resources/META-INF/native-image/resource-config.json
+++ b/examples/graal-native/src/main/resources/META-INF/native-image/resource-config.json
@@ -1,5 +1,7 @@
 {
   "resources":{
-  "includes":[]},
+  "includes":[{
+    "pattern":"\\QMETA-INF/services/java.lang.System$LoggerFinder\\E"
+  }]},
   "bundles":[]
 }
\ No newline at end of file
diff --git a/examples/hibernate/build.gradle.kts b/examples/hibernate/build.gradle.kts
index 7708b7a02f..7ba7a67ebc 100644
--- a/examples/hibernate/build.gradle.kts
+++ b/examples/hibernate/build.gradle.kts
@@ -26,7 +26,7 @@ testing.suites {
 }
 
 java.toolchain.languageVersion = JavaLanguageVersion.of(
-  System.getenv("JAVA_VERSION")?.toIntOrNull() ?: 17)
+  System.getenv("JAVA_VERSION")?.toIntOrNull() ?: 21)
 
 tasks.withType<JavaCompile>().configureEach {
   javaCompiler = javaToolchains.compilerFor {
diff --git a/examples/hibernate/gradle/gradle-daemon-jvm.properties b/examples/hibernate/gradle/gradle-daemon-jvm.properties
new file mode 100644
index 0000000000..63e5bbdf48
--- /dev/null
+++ b/examples/hibernate/gradle/gradle-daemon-jvm.properties
@@ -0,0 +1,2 @@
+#This file is generated by updateDaemonJvm
+toolchainVersion=21
diff --git a/examples/hibernate/gradle/libs.versions.toml b/examples/hibernate/gradle/libs.versions.toml
index 62feaa346b..3dd55d9546 100644
--- a/examples/hibernate/gradle/libs.versions.toml
+++ b/examples/hibernate/gradle/libs.versions.toml
@@ -1,8 +1,8 @@
 [versions]
 caffeine = "3.1.8"
 h2 = "2.2.224"
-hibernate = "6.5.0.CR2"
-junit = "5.10.2"
+hibernate = "6.5.0.Final"
+junit = "5.11.0-M1"
 log4j2 = "3.0.0-beta2"
 slf4j = "2.0.7"
 truth = "1.4.2"
diff --git a/examples/hibernate/gradle/wrapper/gradle-wrapper.properties b/examples/hibernate/gradle/wrapper/gradle-wrapper.properties
index 11fbe40fcb..1de365ecd3 100644
--- a/examples/hibernate/gradle/wrapper/gradle-wrapper.properties
+++ b/examples/hibernate/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-rc-1-bin.zip
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
diff --git a/examples/hibernate/settings.gradle.kts b/examples/hibernate/settings.gradle.kts
index 8a9e1c181e..b21c56b1b6 100644
--- a/examples/hibernate/settings.gradle.kts
+++ b/examples/hibernate/settings.gradle.kts
@@ -1,6 +1,6 @@
 plugins {
-  id("com.gradle.develocity") version "3.17.1"
-  id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0"
+  id("com.gradle.develocity") version "3.17.2"
+  id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.1"
   id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
 }
 
diff --git a/examples/resilience-failsafe/build.gradle.kts b/examples/resilience-failsafe/build.gradle.kts
index 4c3bcd1adc..91f69eba53 100644
--- a/examples/resilience-failsafe/build.gradle.kts
+++ b/examples/resilience-failsafe/build.gradle.kts
@@ -18,7 +18,7 @@ testing.suites {
 }
 
 java.toolchain.languageVersion = JavaLanguageVersion.of(
-  System.getenv("JAVA_VERSION")?.toIntOrNull() ?: 11)
+  System.getenv("JAVA_VERSION")?.toIntOrNull() ?: 21)
 
 tasks.withType<JavaCompile>().configureEach {
   javaCompiler = javaToolchains.compilerFor {
diff --git a/examples/resilience-failsafe/gradle/gradle-daemon-jvm.properties b/examples/resilience-failsafe/gradle/gradle-daemon-jvm.properties
new file mode 100644
index 0000000000..63e5bbdf48
--- /dev/null
+++ b/examples/resilience-failsafe/gradle/gradle-daemon-jvm.properties
@@ -0,0 +1,2 @@
+#This file is generated by updateDaemonJvm
+toolchainVersion=21
diff --git a/examples/resilience-failsafe/gradle/libs.versions.toml b/examples/resilience-failsafe/gradle/libs.versions.toml
index 64453d178e..cf720b8f47 100644
--- a/examples/resilience-failsafe/gradle/libs.versions.toml
+++ b/examples/resilience-failsafe/gradle/libs.versions.toml
@@ -1,7 +1,7 @@
 [versions]
 caffeine = "3.1.8"
 failsafe = "3.3.2"
-junit = "5.10.2"
+junit = "5.11.0-M1"
 truth = "1.4.2"
 versions = "0.51.0"
 
diff --git a/examples/resilience-failsafe/gradle/wrapper/gradle-wrapper.properties b/examples/resilience-failsafe/gradle/wrapper/gradle-wrapper.properties
index 11fbe40fcb..1de365ecd3 100644
--- a/examples/resilience-failsafe/gradle/wrapper/gradle-wrapper.properties
+++ b/examples/resilience-failsafe/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-rc-1-bin.zip
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
diff --git a/examples/resilience-failsafe/settings.gradle.kts b/examples/resilience-failsafe/settings.gradle.kts
index e77767b779..a9014c56c8 100644
--- a/examples/resilience-failsafe/settings.gradle.kts
+++ b/examples/resilience-failsafe/settings.gradle.kts
@@ -1,6 +1,6 @@
 plugins {
-  id("com.gradle.develocity") version "3.17.1"
-  id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0"
+  id("com.gradle.develocity") version "3.17.2"
+  id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.1"
   id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
 }
 
diff --git a/examples/write-behind-rxjava/build.gradle.kts b/examples/write-behind-rxjava/build.gradle.kts
index d7732b9344..78404ca3f1 100644
--- a/examples/write-behind-rxjava/build.gradle.kts
+++ b/examples/write-behind-rxjava/build.gradle.kts
@@ -18,7 +18,7 @@ testing.suites {
 }
 
 java.toolchain.languageVersion = JavaLanguageVersion.of(
-  System.getenv("JAVA_VERSION")?.toIntOrNull() ?: 11)
+  System.getenv("JAVA_VERSION")?.toIntOrNull() ?: 21)
 
 tasks.withType<JavaCompile>().configureEach {
   javaCompiler = javaToolchains.compilerFor {
diff --git a/examples/write-behind-rxjava/gradle/gradle-daemon-jvm.properties b/examples/write-behind-rxjava/gradle/gradle-daemon-jvm.properties
new file mode 100644
index 0000000000..63e5bbdf48
--- /dev/null
+++ b/examples/write-behind-rxjava/gradle/gradle-daemon-jvm.properties
@@ -0,0 +1,2 @@
+#This file is generated by updateDaemonJvm
+toolchainVersion=21
diff --git a/examples/write-behind-rxjava/gradle/libs.versions.toml b/examples/write-behind-rxjava/gradle/libs.versions.toml
index fa0d64b095..651b02d9e1 100644
--- a/examples/write-behind-rxjava/gradle/libs.versions.toml
+++ b/examples/write-behind-rxjava/gradle/libs.versions.toml
@@ -1,7 +1,7 @@
 [versions]
 awaitility = "4.2.1"
 caffeine = "3.1.8"
-junit = "5.10.2"
+junit = "5.11.0-M1"
 rxjava = "3.1.8"
 versions = "0.51.0"
 
diff --git a/examples/write-behind-rxjava/gradle/wrapper/gradle-wrapper.properties b/examples/write-behind-rxjava/gradle/wrapper/gradle-wrapper.properties
index 11fbe40fcb..1de365ecd3 100644
--- a/examples/write-behind-rxjava/gradle/wrapper/gradle-wrapper.properties
+++ b/examples/write-behind-rxjava/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-rc-1-bin.zip
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
diff --git a/examples/write-behind-rxjava/settings.gradle.kts b/examples/write-behind-rxjava/settings.gradle.kts
index 2ef0776bd0..deeb5050c9 100644
--- a/examples/write-behind-rxjava/settings.gradle.kts
+++ b/examples/write-behind-rxjava/settings.gradle.kts
@@ -1,6 +1,6 @@
 plugins {
-  id("com.gradle.develocity") version "3.17.1"
-  id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0"
+  id("com.gradle.develocity") version "3.17.2"
+  id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.1"
   id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
 }
 
diff --git a/gradle/gradle-daemon-jvm.properties b/gradle/gradle-daemon-jvm.properties
new file mode 100644
index 0000000000..63e5bbdf48
--- /dev/null
+++ b/gradle/gradle-daemon-jvm.properties
@@ -0,0 +1,2 @@
+#This file is generated by updateDaemonJvm
+toolchainVersion=21
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 64ed40c55c..138950102f 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -23,7 +23,7 @@ coveralls = "2.12.2"
 dependency-check = "9.1.0"
 eclipse-collections = "12.0.0.M3"
 ehcache3 = "3.10.8"
-errorprone-core = "2.26.1"
+errorprone-core = "2.27.0"
 errorprone-plugin = "3.1.0"
 errorprone-support = "0.16.1"
 expiring-map = "0.5.11"
@@ -57,13 +57,13 @@ jfreechart = "1.5.4"
 jgit = "6.9.0.202403050737-r"
 jmh-core = "1.37"
 jmh-plugin = "0.7.2"
-jmh-report = "0.9.0"
+jmh-report = "0.9.6"
 joor = "0.9.15"
 json-bind = "1.0"
 jsoup = "1.17.2"
 junit-testng = "1.0.5"
 junit4 = "4.13.2"
-junit5 = "5.10.2"
+junit5 = "5.11.0-M1"
 kotlin = "1.9.23"
 lincheck = "2.29"
 mockito = "5.11.0"
@@ -78,7 +78,7 @@ osgi-promise = "1.3.0"
 pax-exam = "4.13.5"
 pax-url = "2.6.14"
 picocli = "4.7.5"
-pmd = "7.0.0"
+pmd = "7.1.0"
 protobuf = "4.26.1"
 slf4j = "2.0.13"
 slf4j-test = "3.0.1"
@@ -96,7 +96,7 @@ versions = "0.51.0"
 xz = "1.9"
 ycsb = "0.17.0"
 zero-allocation-hashing = "0.16"
-zstd = "1.5.6-2"
+zstd = "1.5.6-3"
 
 [libraries]
 asm-bom = { module = "org.ow2.asm:asm-bom", version.ref = "asm" }
diff --git a/gradle/plugins/gradle/gradle-daemon-jvm.properties b/gradle/plugins/gradle/gradle-daemon-jvm.properties
new file mode 100644
index 0000000000..63e5bbdf48
--- /dev/null
+++ b/gradle/plugins/gradle/gradle-daemon-jvm.properties
@@ -0,0 +1,2 @@
+#This file is generated by updateDaemonJvm
+toolchainVersion=21
diff --git a/gradle/plugins/settings.gradle.kts b/gradle/plugins/settings.gradle.kts
index 323e54a0c7..182ab4b6c3 100644
--- a/gradle/plugins/settings.gradle.kts
+++ b/gradle/plugins/settings.gradle.kts
@@ -1,6 +1,6 @@
 plugins {
-  id("com.gradle.develocity") version "3.17.1"
-  id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0"
+  id("com.gradle.develocity") version "3.17.2"
+  id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.1"
   id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
 }
 
diff --git a/gradle/plugins/src/main/kotlin/lifecycle/dependency-versions-caffeine-conventions.gradle.kts b/gradle/plugins/src/main/kotlin/lifecycle/dependency-versions-caffeine-conventions.gradle.kts
index ada747dfa5..82ef0ccff0 100644
--- a/gradle/plugins/src/main/kotlin/lifecycle/dependency-versions-caffeine-conventions.gradle.kts
+++ b/gradle/plugins/src/main/kotlin/lifecycle/dependency-versions-caffeine-conventions.gradle.kts
@@ -18,6 +18,7 @@ tasks.named<DependencyUpdatesTask>("dependencyUpdates").configure {
       }
     }
     force(libs.guice)
+    force(libs.hazelcast)
     force(libs.commons.collections4)
     force(libs.bundles.coherence.get())
   }
diff --git a/gradle/plugins/src/main/kotlin/lifecycle/testing-caffeine-conventions.gradle.kts b/gradle/plugins/src/main/kotlin/lifecycle/testing-caffeine-conventions.gradle.kts
index d8d7feea29..70f6d35442 100644
--- a/gradle/plugins/src/main/kotlin/lifecycle/testing-caffeine-conventions.gradle.kts
+++ b/gradle/plugins/src/main/kotlin/lifecycle/testing-caffeine-conventions.gradle.kts
@@ -41,6 +41,10 @@ tasks.withType<Test>().configureEach {
     jvmArgs("-XX:+UnlockExperimentalVMOptions", "-Dgraal.ShowConfiguration=info",
       "-XX:+EnableJVMCI", "-XX:+UseJVMCICompiler", "-XX:+EagerJVMCI")
   }
+  if (System.getenv().contains("CI")) {
+    reports.junitXml.includeSystemOutLog = false
+    reports.junitXml.includeSystemErrLog = false
+  }
   testLogging {
     events = setOf(SKIPPED, FAILED)
     exceptionFormat = FULL
diff --git a/gradle/plugins/src/main/kotlin/quality/errorprone-caffeine-conventions.gradle.kts b/gradle/plugins/src/main/kotlin/quality/errorprone-caffeine-conventions.gradle.kts
index 6b9e5e51b5..bedadc84bd 100644
--- a/gradle/plugins/src/main/kotlin/quality/errorprone-caffeine-conventions.gradle.kts
+++ b/gradle/plugins/src/main/kotlin/quality/errorprone-caffeine-conventions.gradle.kts
@@ -110,6 +110,7 @@ fun enabledChecks() = listOf(
   "MissingDefault",
   "MixedArrayDimensions",
   "MissingDefault",
+  "MockitoDoSetup",
   "MutableGuiceModule",
   "NoAllocation",
   "NonFinalStaticField",
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 11fbe40fcb..1de365ecd3 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-rc-1-bin.zip
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
diff --git a/jcache/build.gradle.kts b/jcache/build.gradle.kts
index c2ba2fe0c2..b8c5757de3 100644
--- a/jcache/build.gradle.kts
+++ b/jcache/build.gradle.kts
@@ -19,7 +19,7 @@ val jcacheTckSources: Configuration by configurations.creating
 
 val testResourcesJar by tasks.registering(Jar::class) {
   from(sourceSets["testResources"].output)
-  archiveClassifier.set("test-resources")
+  archiveClassifier = "test-resources"
   outputs.cacheIf { true }
 }
 
diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/CacheProxyTest.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/CacheProxyTest.java
index affa7ceefa..6f4f9351e2 100644
--- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/CacheProxyTest.java
+++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/CacheProxyTest.java
@@ -125,7 +125,7 @@ public void getConfiguration_immutable() {
 
   @Test
   public void load_cacheLoaderException() {
-    var listener = Mockito.mock(CompletionListener.class);
+    CompletionListener listener = Mockito.mock();
     var e = new CacheLoaderException();
     doThrow(e).when(listener).onCompletion();
     jcache.loadAll(keys, true, listener);
diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/event/EventTypeAwareListenerTest.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/event/EventTypeAwareListenerTest.java
index 65f09959b0..635aa986a1 100644
--- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/event/EventTypeAwareListenerTest.java
+++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/event/EventTypeAwareListenerTest.java
@@ -52,7 +52,7 @@ public void before() throws Exception {
   @Test
   public void closed() throws IOException {
     when(cache.isClosed()).thenReturn(true);
-    var listener = Mockito.mock(CacheEntryListener.class);
+    CacheEntryListener<Integer, Integer> listener = Mockito.mock();
     try (var forwarder = new EventTypeAwareListener<>(listener)) {
       forwarder.dispatch(new JCacheEntryEvent<>(cache, EventType.CREATED,
           /* key */ 1, /* hasOldValue */ false, /* oldValue */ null, /* newValue */ 2));
diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/management/JmxRegistrationTest.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/management/JmxRegistrationTest.java
index 625fde1cf1..9821562058 100644
--- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/management/JmxRegistrationTest.java
+++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/management/JmxRegistrationTest.java
@@ -44,7 +44,7 @@ public final class JmxRegistrationTest {
   public void register_error(Class<? extends Throwable> throwableType) throws JMException {
     var name = new ObjectName("");
     var bean = new JCacheStatisticsMXBean();
-    var server = Mockito.mock(MBeanServer.class);
+    MBeanServer server = Mockito.mock();
     when(server.registerMBean(bean, name)).thenThrow(throwableType);
     assertThrows(CacheException.class, () -> JmxRegistration.register(server, name, bean));
   }
@@ -52,7 +52,7 @@ public void register_error(Class<? extends Throwable> throwableType) throws JMEx
   @Test(dataProvider = "unegisterExceptions")
   public void unregister_error(Class<? extends Throwable> throwableType) throws JMException {
     var name = new ObjectName("");
-    var server = Mockito.mock(MBeanServer.class);
+    MBeanServer server = Mockito.mock();
     when(server.queryNames(any(), any())).thenReturn(Set.of(name));
     doThrow(throwableType).when(server).unregisterMBean(any());
     assertThrows(CacheException.class, () -> JmxRegistration.unregister(server, name));
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 3c8a63a337..bdf0ccfdd1 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -2,8 +2,8 @@ pluginManagement {
   includeBuild("gradle/plugins")
 }
 plugins {
-  id("com.gradle.develocity") version "3.17.1"
-  id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0"
+  id("com.gradle.develocity") version "3.17.2"
+  id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.1"
   id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
 }