From 0bbbb9692c99d175aec80a4e3303100b4cba277b Mon Sep 17 00:00:00 2001 From: Ben Manes Date: Sat, 14 Dec 2024 11:08:03 -0800 Subject: [PATCH] enable nullaway on unit tests (wip) --- .gitignore | 1 + caffeine/build.gradle.kts | 1 + .../caffeine/cache/BoundedLocalCache.java | 2 + .../caffeine/cache/AsyncAsMapTest.java | 28 +++++++----- .../caffeine/cache/AsyncCacheTest.java | 28 +++++++++++- .../caffeine/cache/BoundedLocalCacheTest.java | 14 +++++- .../caffeine/cache/CaffeineSpecGuavaTest.java | 4 ++ .../benmanes/caffeine/cache/EvictionTest.java | 4 ++ .../caffeine/cache/LinkedDequeSubject.java | 8 +++- .../caffeine/cache/LocalCacheSubject.java | 43 +++++++++++-------- .../caffeine/cache/ReserializableSubject.java | 10 +++-- .../caffeine/cache/SchedulerTest.java | 2 + .../cache/testing/AsyncCacheSubject.java | 11 +++-- .../caffeine/cache/testing/CacheContext.java | 12 ++++-- .../cache/testing/CacheContextSubject.java | 13 +++--- .../caffeine/cache/testing/CacheSpec.java | 20 ++++++--- .../caffeine/cache/testing/CacheSubject.java | 16 ++++--- .../cache/testing/GuavaCacheFromContext.java | 18 +++++--- .../cache/testing/RemovalListeners.java | 8 ++-- .../caffeine/cache/testing/Weighers.java | 5 ++- .../ConcurrentHashMapAcceptanceTest.java | 2 + .../caffeine/testing/CollectionSubject.java | 8 +++- .../caffeine/testing/FutureSubject.java | 18 ++++++-- .../github/benmanes/caffeine/testing/Int.java | 7 ++- .../benmanes/caffeine/testing/IntSubject.java | 6 ++- .../caffeine/testing/LoggingEvents.java | 4 +- .../benmanes/caffeine/testing/MapSubject.java | 14 ++++-- .../gradle/libs.versions.toml | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../settings.gradle.kts | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- examples/graal-native/settings.gradle.kts | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- examples/hibernate/settings.gradle.kts | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- examples/indexable/settings.gradle.kts | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../resilience-failsafe/settings.gradle.kts | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../write-behind-rxjava/settings.gradle.kts | 2 +- gradle/libs.versions.toml | 10 ++--- gradle/plugins/settings.gradle.kts | 2 +- .../quality/errorprone.caffeine.gradle.kts | 2 + gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle.kts | 4 +- 45 files changed, 248 insertions(+), 105 deletions(-) diff --git a/.gitignore b/.gitignore index 8f6fc3c8dd..e3764d839f 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ jitwatch.out .settings .project .gradle +.kotlin .vscode .idea *.iml diff --git a/caffeine/build.gradle.kts b/caffeine/build.gradle.kts index b923f49914..48b1fa59b6 100644 --- a/caffeine/build.gradle.kts +++ b/caffeine/build.gradle.kts @@ -140,6 +140,7 @@ tasks.named("compileJava").configure { tasks.named("compileTestJava").configure { dependsOn(tasks.jar, compileCodeGenJava) options.errorprone { + disable("IdentifierName") disable("Varifier") disable("Var") } diff --git a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedLocalCache.java b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedLocalCache.java index 3d5d2314f2..20a71a3da1 100644 --- a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedLocalCache.java +++ b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedLocalCache.java @@ -3163,6 +3163,7 @@ T expireAfterAccessOrder(boolean oldest, Function<@Nullable V, @Nullable V> * @param mappingFunction the mapping function to compute a value * @return the computed value */ + @SuppressWarnings("NullAway") T snapshot(Iterable> iterable, Function<@Nullable V, @Nullable V> transformer, Function>, T> mappingFunction) { requireNonNull(mappingFunction); @@ -4009,6 +4010,7 @@ static final class BoundedPolicy implements Policy { @Override public @Nullable V getIfPresentQuietly(K key) { return transformer.apply(cache.getIfPresentQuietly(key)); } + @SuppressWarnings("NullAway") @Override public @Nullable CacheEntry getEntryIfPresentQuietly(K key) { Node node = cache.data.get(cache.nodeFactory.newLookupKey(key)); return (node == null) ? null : cache.nodeToCacheEntry(node, transformer); 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 57dd96cb68..8c61bf4c40 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 @@ -28,6 +28,7 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableMap.toImmutableMap; import static com.google.common.truth.Truth.assertThat; +import static java.util.Objects.requireNonNull; import static java.util.function.Function.identity; import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; @@ -292,8 +293,8 @@ public void put_insert(AsyncCache cache, CacheContext context) { public void put_replace_sameValue(AsyncCache cache, CacheContext context) { var replaced = new HashMap(); for (Int key : context.firstMiddleLastKeys()) { - var oldValue = cache.asMap().get(key); - var value = cache.asMap().get(key).thenApply(val -> intern(new Int(val))); + var oldValue = requireNonNull(cache.asMap().get(key)); + var value = oldValue.thenApply(val -> intern(new Int(val))); assertThat(cache.asMap().put(key, value)).isSameInstanceAs(oldValue); assertThat(cache).containsEntry(key, value); replaced.put(key, context.original().get(key)); @@ -307,7 +308,7 @@ public void put_replace_sameValue(AsyncCache cache, CacheContext conte @CacheSpec(population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }) public void put_replace_sameInstance(AsyncCache cache, CacheContext context) { for (Int key : context.firstMiddleLastKeys()) { - var value = cache.asMap().get(key); + var value = requireNonNull(cache.asMap().get(key)); assertThat(cache.asMap().put(key, value)).isSameInstanceAs(value); assertThat(cache).containsEntry(key, value); } @@ -435,7 +436,7 @@ public void putIfAbsent_nullKeyAndValue(AsyncCache cache, CacheContext removalListener = { Listener.DISABLED, Listener.REJECTING }) public void putIfAbsent_present(AsyncCache cache, CacheContext context) { for (Int key : context.firstMiddleLastKeys()) { - var value = cache.asMap().get(key); + var value = requireNonNull(cache.asMap().get(key)); assertThat(cache.asMap().putIfAbsent(key, key.asFuture())).isEqualTo(value); assertThat(cache).containsEntry(key, value); } @@ -589,8 +590,8 @@ public void replace_failure(AsyncCache cache, CacheContext context) { public void replace_sameValue(AsyncCache cache, CacheContext context) { var replaced = new HashMap(); for (Int key : context.firstMiddleLastKeys()) { - var oldValue = cache.asMap().get(key); - var newValue = cache.asMap().get(key).thenApply(val -> intern(new Int(val))); + var oldValue = requireNonNull(cache.asMap().get(key)); + var newValue = oldValue.thenApply(val -> intern(new Int(val))); assertThat(cache.asMap().replace(key, newValue)).isSameInstanceAs(oldValue); assertThat(cache).containsEntry(key, newValue); replaced.put(key, context.original().get(key)); @@ -718,8 +719,8 @@ public void replaceConditionally_wrongOldValue(AsyncCache cache, Cache public void replaceConditionally_sameValue(AsyncCache cache, CacheContext context) { var replaced = new HashMap(); for (Int key : context.firstMiddleLastKeys()) { - var oldValue = cache.asMap().get(key); - var newValue = cache.asMap().get(key).thenApply(val -> intern(new Int(val))); + var oldValue = requireNonNull(cache.asMap().get(key)); + var newValue = oldValue.thenApply(val -> intern(new Int(val))); assertThat(cache.asMap().replace(key, oldValue, newValue)).isTrue(); assertThat(cache).containsEntry(key, newValue); replaced.put(key, context.original().get(key)); @@ -1310,7 +1311,7 @@ public void merge_absent(AsyncCache cache, CacheContext context) { public void merge_sameValue(AsyncCache cache, CacheContext context) { var replaced = new HashMap>(); for (Int key : context.firstMiddleLastKeys()) { - var value = cache.asMap().get(key).thenApply(Int::new); + var value = requireNonNull(cache.asMap().get(key)).thenApply(Int::new); var result = cache.asMap().merge(key, key.negate().asFuture(), (oldValue, v) -> value); assertThat(result).isSameInstanceAs(value); replaced.put(key, value); @@ -1566,7 +1567,9 @@ public void keySet_removeAll_partial(AsyncCache cache, CacheContext co assertThat(cache.asMap().keySet().removeAll(context.firstMiddleLastKeys())).isTrue(); assertThat(cache.synchronous().asMap()).isEqualTo(expected); assertThat(context).removalNotifications().withCause(EXPLICIT) - .contains(Maps.asMap(context.firstMiddleLastKeys(), context.original()::get)).exclusively(); + .contains(Maps.asMap(context.firstMiddleLastKeys(), + key -> requireNonNull(context.original().get(key)))) + .exclusively(); } @CheckNoStats @@ -1739,7 +1742,9 @@ public void keySet_retainAll_partial(AsyncCache cache, CacheContext co assertThat(cache.asMap().keySet().retainAll(expected.keySet())).isTrue(); assertThat(cache.asMap()).isEqualTo(expected); assertThat(context).removalNotifications().withCause(EXPLICIT) - .contains(Maps.asMap(context.firstMiddleLastKeys(), context.original()::get)).exclusively(); + .contains(Maps.asMap(context.firstMiddleLastKeys(), + key -> requireNonNull(context.original().get(key)))) + .exclusively(); } @CheckNoStats @@ -1872,6 +1877,7 @@ public void keySpliterator_estimateSize(AsyncCache cache, CacheContext /* ---------------- Values -------------- */ @CheckNoStats + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DISABLED, Listener.REJECTING }) public void values_toArray_null(AsyncCache cache, CacheContext context) { diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncCacheTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncCacheTest.java index 908b1b6157..e7954b127c 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncCacheTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncCacheTest.java @@ -29,6 +29,7 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableMap.toImmutableMap; import static com.google.common.truth.Truth.assertThat; +import static java.util.Objects.requireNonNull; import static java.util.function.Function.identity; import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; @@ -85,6 +86,7 @@ public final class AsyncCacheTest { /* --------------- getIfPresent --------------- */ + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DISABLED, Listener.REJECTING }) public void getIfPresent_nullKey(AsyncCache cache, CacheContext context) { @@ -111,12 +113,14 @@ public void getIfPresent_present(AsyncCache cache, CacheContext contex /* --------------- getFunc --------------- */ @CacheSpec + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") public void getFunc_nullKey(AsyncCache cache, CacheContext context) { assertThrows(NullPointerException.class, () -> cache.get(null, key -> null)); } @CacheSpec + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") public void getFunc_nullLoader(AsyncCache cache, CacheContext context) { Function mappingFunction = null; @@ -124,6 +128,7 @@ public void getFunc_nullLoader(AsyncCache cache, CacheContext context) } @CacheSpec + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") public void getFunc_nullKeyAndLoader(AsyncCache cache, CacheContext context) { assertThrows(NullPointerException.class, () -> cache.get(null, (Function) null)); @@ -133,6 +138,7 @@ public void getFunc_nullKeyAndLoader(AsyncCache cache, CacheContext co @Test(dataProvider = "caches") public void getFunc_absent_null(AsyncCache cache, CacheContext context) { Int key = context.absentKey(); + @SuppressWarnings("NullAway") var valueFuture = cache.get(key, k -> null); assertThat(context).stats().hits(0).misses(1).success(0).failures(1); @@ -140,12 +146,12 @@ public void getFunc_absent_null(AsyncCache cache, CacheContext context assertThat(cache).doesNotContainKey(key); } - @Test(dataProvider = "caches") @CacheSpec(executor = CacheExecutor.THREADED, executorFailure = ExecutorFailure.IGNORED) public void getFunc_absent_null_async(AsyncCache cache, CacheContext context) { Int key = context.absentKey(); var ready = new AtomicBoolean(); var done = new AtomicBoolean(); + @SuppressWarnings("NullAway") var valueFuture = cache.get(key, k -> { await().untilTrue(ready); return null; @@ -201,6 +207,7 @@ public void getFunc_absent_failure_async(AsyncCache cache, CacheContex @CacheSpec(executor = CacheExecutor.THREADED, executorFailure = ExecutorFailure.IGNORED) public void getFunc_absent_cancelled(AsyncCache cache, CacheContext context) { var done = new AtomicBoolean(); + @SuppressWarnings("NullAway") var valueFuture = cache.get(context.absentKey(), k -> { await().until(done::get); return null; @@ -241,6 +248,7 @@ public void getFunc_present(AsyncCache cache, CacheContext context) { /* --------------- getBiFunc --------------- */ @CacheSpec + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") public void getBiFunc_nullKey(AsyncCache cache, CacheContext context) { assertThrows(NullPointerException.class, () -> @@ -248,6 +256,7 @@ public void getBiFunc_nullKey(AsyncCache cache, CacheContext context) } @CacheSpec + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") public void getBiFunc_nullLoader(AsyncCache cache, CacheContext context) { BiFunction> mappingFunction = null; @@ -255,6 +264,7 @@ public void getBiFunc_nullLoader(AsyncCache cache, CacheContext contex } @CacheSpec + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") public void getBiFunc_nullKeyAndLoader(AsyncCache cache, CacheContext context) { BiFunction> mappingFunction = null; @@ -372,6 +382,7 @@ public void getBiFunc_present(AsyncCache cache, CacheContext context) /* --------------- getAllFunc --------------- */ @CheckNoStats + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DISABLED, Listener.REJECTING }) public void getAllFunction_nullKeys(AsyncCache cache, CacheContext context) { @@ -380,6 +391,7 @@ public void getAllFunction_nullKeys(AsyncCache cache, CacheContext con } @CheckNoStats + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DISABLED, Listener.REJECTING }) public void getAllFunction_nullKeys_nullFunction( @@ -389,6 +401,7 @@ public void getAllFunction_nullKeys_nullFunction( } @CheckNoStats + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DISABLED, Listener.REJECTING }) public void getAllFunction_nullFunction(AsyncCache cache, CacheContext context) { @@ -413,6 +426,7 @@ public void getAllFunction_iterable_empty(AsyncCache cache, CacheConte assertThat(result).isExhaustivelyEmpty(); } + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DISABLED, Listener.REJECTING }) public void getAllFunction_nullLookup(AsyncCache cache, CacheContext context) { @@ -443,6 +457,7 @@ public void getAllFunction_immutable_result(AsyncCache cache, CacheCon } @CacheSpec + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") public void getAllFunction_absent_null(AsyncCache cache, CacheContext context) { assertThat(cache.getAll(context.absentKeys(), keys -> null)) @@ -609,6 +624,7 @@ public void getAllFunction_canceled_individual(AsyncCache cache, Cache }); for (var key : context.absentKeys()) { var future = cache.getIfPresent(key); + requireNonNull(future); future.cancel(true); assertThat(future).hasCompletedExceptionally(); } @@ -655,6 +671,7 @@ public void getAllFunction_badLoader(AsyncCache cache, CacheContext co /* --------------- getAllBiFunc --------------- */ @CheckNoStats + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DISABLED, Listener.REJECTING }) public void getAllBifunction_nullKeys(AsyncCache cache, CacheContext context) { @@ -663,6 +680,7 @@ public void getAllBifunction_nullKeys(AsyncCache cache, CacheContext c } @CheckNoStats + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DISABLED, Listener.REJECTING }) public void getAllBifunction_nullKeys_nullBifunction( @@ -672,6 +690,7 @@ public void getAllBifunction_nullKeys_nullBifunction( } @CheckNoStats + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DISABLED, Listener.REJECTING }) public void getAllBifunction_nullBifunction(AsyncCache cache, CacheContext context) { @@ -938,6 +957,7 @@ public void getAllBifunction_canceled_individual( }); for (var key : context.absentKeys()) { var future = cache.getIfPresent(key); + requireNonNull(future); future.cancel(true); assertThat(future).hasCompletedExceptionally(); } @@ -1010,6 +1030,7 @@ public void getAllBifunction_early_success(AsyncCache cache, CacheCont var result = cache.getAll(context.absentKeys(), (keysToLoad, executor) -> bulk); var future = cache.asMap().get(key); + requireNonNull(future); future.complete(value); bulk.complete(context.absent()); // obtrudes the future's value @@ -1027,6 +1048,8 @@ public void getAllBifunction_early_failure(AsyncCache cache, CacheCont var bulk = new CompletableFuture>(); var result = cache.getAll(context.absentKeys(), (keysToLoad, executor) -> bulk); var future = cache.asMap().get(key); + + requireNonNull(future); future.completeExceptionally(error); bulk.complete(context.absent()); @@ -1043,6 +1066,7 @@ public void getAllBifunction_early_failure(AsyncCache cache, CacheCont /* --------------- put --------------- */ + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DISABLED, Listener.REJECTING }) public void put_nullKey(AsyncCache cache, CacheContext context) { @@ -1050,12 +1074,14 @@ public void put_nullKey(AsyncCache cache, CacheContext context) { assertThrows(NullPointerException.class, () -> cache.put(null, value)); } + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DISABLED, Listener.REJECTING }) public void put_nullValue(AsyncCache cache, CacheContext context) { assertThrows(NullPointerException.class, () -> cache.put(context.absentKey(), null)); } + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DISABLED, Listener.REJECTING }) public void put_nullKeyAndValue(AsyncCache cache, CacheContext context) { 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 42d54382ab..a03be45ef8 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 @@ -998,8 +998,13 @@ public void evict_retired_victim(BoundedLocalCache cache, CacheContext @Test(dataProvider = "caches") @CacheSpec(compute = Compute.SYNC, population = Population.EMPTY, - maximumSize = Maximum.FULL, weigher = CacheWeigher.VALUE) + maximumSize = Maximum.FULL, weigher = CacheWeigher.MOCKITO) public void evict_zeroWeight_candidate(BoundedLocalCache cache, CacheContext context) { + when(context.weigher().weigh(any(), any())).thenAnswer(invocation -> { + Int value = invocation.getArgument(1); + return Math.abs(value.intValue()); + }); + for (int i = 0; i < context.maximumSize(); i++) { assertThat(cache.put(Int.valueOf(i), Int.valueOf(1))).isNull(); } @@ -1019,8 +1024,13 @@ public void evict_zeroWeight_candidate(BoundedLocalCache cache, CacheC @Test(dataProvider = "caches") @CacheSpec(compute = Compute.SYNC, population = Population.EMPTY, - maximumSize = Maximum.FULL, weigher = CacheWeigher.VALUE) + maximumSize = Maximum.FULL, weigher = CacheWeigher.MOCKITO) public void evict_zeroWeight_victim(BoundedLocalCache cache, CacheContext context) { + when(context.weigher().weigh(any(), any())).thenAnswer(invocation -> { + Int value = invocation.getArgument(1); + return Math.abs(value.intValue()); + }); + for (int i = 0; i < context.maximumSize(); i++) { assertThat(cache.put(Int.valueOf(i), Int.valueOf(1))).isNull(); } diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CaffeineSpecGuavaTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CaffeineSpecGuavaTest.java index aa2b2fc4dd..4b01a97910 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CaffeineSpecGuavaTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CaffeineSpecGuavaTest.java @@ -354,21 +354,25 @@ public void testEqualsAndHashCode() { .testEquals(); } + @SuppressWarnings("NullAway") public void testMaximumWeight_withWeigher() { Caffeine builder = Caffeine.from(parse("maximumWeight=9000")); assertThat(builder.weigher((k, v) -> 42).build(k -> null)).isNotNull(); } + @SuppressWarnings("NullAway") public void testMaximumWeight_withoutWeigher() { Caffeine builder = Caffeine.from(parse("maximumWeight=9000")); assertThrows(IllegalStateException.class, () -> builder.build(k -> null)); } + @SuppressWarnings("NullAway") public void testMaximumSize_withWeigher() { Caffeine builder = Caffeine.from(parse("maximumSize=9000")); assertThat(builder.weigher((k, v) -> 42).build(k -> null)).isNotNull(); } + @SuppressWarnings("NullAway") public void testMaximumSize_withoutWeigher() { Caffeine builder = Caffeine.from(parse("maximumSize=9000")); assertThat(builder.build(k -> null)).isNotNull(); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/EvictionTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/EvictionTest.java index ca451325d4..e72fe319fe 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/EvictionTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/EvictionTest.java @@ -1199,12 +1199,14 @@ public void coldest_snapshot(Cache cache, assertThat(coldest).containsExactlyEntriesIn(context.original()); } + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(initialCapacity = InitialCapacity.EXCESSIVE, maximumSize = Maximum.FULL) public void coldestFunc_null(CacheContext context, Eviction eviction) { assertThrows(NullPointerException.class, () -> eviction.coldest(null)); } + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(initialCapacity = InitialCapacity.EXCESSIVE, maximumSize = Maximum.FULL) public void coldestFunc_nullResult(CacheContext context, Eviction eviction) { @@ -1404,12 +1406,14 @@ public void hottest_snapshot(Cache cache, assertThat(hottest).containsExactlyEntriesIn(context.original()); } + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(initialCapacity = InitialCapacity.EXCESSIVE, maximumSize = Maximum.FULL) public void hottestFunc_null(CacheContext context, Eviction eviction) { assertThrows(NullPointerException.class, () -> eviction.hottest(null)); } + @SuppressWarnings("NullAway") @Test(dataProvider = "caches") @CacheSpec(initialCapacity = InitialCapacity.EXCESSIVE, maximumSize = Maximum.FULL) public void hottestFunc_nullResult(CacheContext context, Eviction eviction) { diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeSubject.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeSubject.java index 209b281e48..f1766c5e76 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeSubject.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeSubject.java @@ -16,9 +16,12 @@ package com.github.benmanes.caffeine.cache; import static com.google.common.truth.Truth.assertAbout; +import static java.util.Objects.requireNonNull; import java.util.Iterator; +import org.jspecify.annotations.Nullable; + import com.github.benmanes.caffeine.testing.CollectionSubject; import com.google.common.collect.Sets; import com.google.common.truth.FailureMetadata; @@ -32,9 +35,10 @@ final class LinkedDequeSubject extends CollectionSubject { private final LinkedDeque actual; @SuppressWarnings("unchecked") - private LinkedDequeSubject(FailureMetadata metadata, LinkedDeque subject) { + private LinkedDequeSubject(FailureMetadata metadata, @Nullable LinkedDeque subject) { super(metadata, subject); - this.actual = (LinkedDeque) subject; + this.actual = requireNonNull((LinkedDeque) subject); + } public static Factory> deque() { diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LocalCacheSubject.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LocalCacheSubject.java index e4163ad913..13890f5654 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LocalCacheSubject.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LocalCacheSubject.java @@ -19,6 +19,7 @@ import static com.github.benmanes.caffeine.testing.Awaits.await; import static com.github.benmanes.caffeine.testing.MapSubject.map; import static com.google.common.truth.Truth.assertThat; +import static java.util.Objects.requireNonNull; import java.util.Collection; import java.util.Map; @@ -26,6 +27,8 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; + import com.github.benmanes.caffeine.cache.Async.AsyncWeigher; import com.github.benmanes.caffeine.cache.BoundedLocalCache.BoundedLocalAsyncCache; import com.github.benmanes.caffeine.cache.BoundedLocalCache.BoundedLocalAsyncLoadingCache; @@ -38,7 +41,7 @@ import com.github.benmanes.caffeine.cache.UnboundedLocalCache.UnboundedLocalAsyncLoadingCache; import com.github.benmanes.caffeine.cache.UnboundedLocalCache.UnboundedLocalManualCache; import com.github.benmanes.caffeine.cache.stats.StatsCounter; -import com.github.benmanes.caffeine.cache.testing.Weighers; +import com.github.benmanes.caffeine.cache.testing.Weighers.SkippedWeigher; import com.google.common.collect.ImmutableTable; import com.google.common.collect.Sets; import com.google.common.truth.FailureMetadata; @@ -54,9 +57,9 @@ public final class LocalCacheSubject extends Subject { private final Object actual; - private LocalCacheSubject(FailureMetadata metadata, Object subject) { + private LocalCacheSubject(FailureMetadata metadata, @Nullable Object subject) { super(metadata, subject); - this.actual = subject; + this.actual = requireNonNull(subject); } public static Factory> asyncLocal() { @@ -298,11 +301,12 @@ private void checkLinks(BoundedLocalCache bounded, long totalWeightedSize = 0; Set> seen = Sets.newIdentityHashSet(); for (var cell : deques.cellSet()) { - long weightedSize = scanLinks(bounded, cell.getValue(), seen); - check("%s: %s in %s", cell.getRowKey(), cell.getValue(), bounded.data) + var deque = requireNonNull(cell.getValue()); + long weightedSize = scanLinks(bounded, deque, seen); + check("%s: %s in %s", cell.getRowKey(), deque, bounded.data) .that(weightedSize).isEqualTo(cell.getColumnKey()); - totalSize += cell.getValue().size(); totalWeightedSize += weightedSize; + totalSize += deque.size(); } check("linkSize").withMessage("cache.size() != links").that(bounded).hasSize(seen.size()); check("totalSize").withMessage("cache.size() == deque.size()").that(bounded).hasSize(totalSize); @@ -354,7 +358,7 @@ private void checkNode(BoundedLocalCache bounded, Node bounded, - Node node, Object key, Object value) { + Node node, @Nullable Object key, @Nullable Object value) { if (bounded.collectKeys()) { if ((key != null) && (value != null)) { check("bounded").that(bounded).containsKey(key); @@ -368,10 +372,11 @@ private void checkKey(BoundedLocalCache bounded, } private void checkValue(BoundedLocalCache bounded, - Node node, Object key, Object value) { + Node node, @Nullable Object key, @Nullable Object value) { if (!bounded.collectValues()) { check("value").that(value).isNotNull(); if ((key != null) && !bounded.hasExpired(node, bounded.expirationTicker().read())) { + requireNonNull(value); check("containsValue(value) for key %s", key) .about(map()).that(bounded).containsValue(value); } @@ -379,7 +384,7 @@ private void checkValue(BoundedLocalCache bounded, checkIfAsyncValue(value); } - private void checkIfAsyncValue(Object value) { + private void checkIfAsyncValue(@Nullable Object value) { if (value instanceof CompletableFuture) { var future = (CompletableFuture) value; if (!future.isDone() || future.isCompletedExceptionally()) { @@ -390,18 +395,22 @@ private void checkIfAsyncValue(Object value) { } private void checkWeight(BoundedLocalCache bounded, - Node node, Object key, Object value) { + Node node, @Nullable Object key, @Nullable Object value) { check("node.getWeight").that(node.getWeight()).isAtLeast(0); + if ((key == null) || (value == null)) { + return; + } - var weigher = bounded.weigher; - boolean canCheckWeight = (weigher == Weighers.random()); + Weigher weigher = bounded.weigher; if (weigher instanceof AsyncWeigher) { - @SuppressWarnings("rawtypes") - var asyncWeigher = (AsyncWeigher) weigher; - canCheckWeight = (asyncWeigher.delegate == Weighers.random()); + weigher = ((AsyncWeigher) weigher).delegate; + } + if (weigher instanceof BoundedWeigher) { + weigher = ((BoundedWeigher) weigher).delegate; } - if (canCheckWeight) { - check("node.getWeight()").that(node.getWeight()).isEqualTo(weigher.weigh(key, value)); + if (!(weigher instanceof SkippedWeigher)) { + int weight = bounded.weigher.weigh(key, value); + check("node.getWeight()").that(node.getWeight()).isEqualTo(weight); } } diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ReserializableSubject.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ReserializableSubject.java index 533d351ef9..46de128f79 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ReserializableSubject.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ReserializableSubject.java @@ -17,6 +17,9 @@ import static com.github.benmanes.caffeine.cache.testing.AsyncCacheSubject.asyncCache; import static com.github.benmanes.caffeine.cache.testing.CacheSubject.cache; +import static java.util.Objects.requireNonNull; + +import org.jspecify.annotations.Nullable; import com.github.benmanes.caffeine.cache.Async.AsyncEvictionListener; import com.github.benmanes.caffeine.cache.Async.AsyncExpiry; @@ -39,9 +42,9 @@ public final class ReserializableSubject extends Subject { private final Object actual; - private ReserializableSubject(FailureMetadata metadata, Object subject) { + private ReserializableSubject(FailureMetadata metadata, @Nullable Object subject) { super(metadata, subject); - this.actual = subject; + this.actual = requireNonNull(subject); } public static Factory> asyncReserializable() { @@ -257,7 +260,8 @@ private void checkUnboundedLocalCache( UnboundedLocalCache original, UnboundedLocalCache copy) { check("isRecordingStats").that(copy.isRecordingStats).isEqualTo(original.isRecordingStats); - if (original.removalListener == null) { + if ((original.removalListener == null) || (copy.removalListener == null)) { + check("removalListener").that(original.removalListener).isNull(); check("removalListener").that(copy.removalListener).isNull(); } else if (copy.removalListener.getClass() != original.removalListener.getClass()) { check("removalListener").that(copy.removalListener).isNotNull(); 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 5864fd7cc3..fd5b09fe90 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 @@ -125,6 +125,7 @@ public void disabledFuture_null() { /* --------------- guarded --------------- */ @Test + @SuppressWarnings("NullAway") public void guardedScheduler_null() { assertThrows(NullPointerException.class, () -> Scheduler.guardedScheduler(null)); } @@ -166,6 +167,7 @@ public void guardedScheduler_exception() { /* --------------- ScheduledExecutorService --------------- */ @Test + @SuppressWarnings("NullAway") public void scheduledExecutorService_null() { assertThrows(NullPointerException.class, () -> Scheduler.forScheduledExecutorService(null)); } diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/AsyncCacheSubject.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/AsyncCacheSubject.java index 02d56c2bb0..d2adb0dd9b 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/AsyncCacheSubject.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/AsyncCacheSubject.java @@ -20,10 +20,13 @@ import static com.github.benmanes.caffeine.cache.testing.CacheSubject.cache; import static com.github.benmanes.caffeine.testing.MapSubject.map; import static com.google.common.truth.Truth.assertAbout; +import static java.util.Objects.requireNonNull; import java.util.Map; import java.util.concurrent.Future; +import org.jspecify.annotations.Nullable; + import com.github.benmanes.caffeine.cache.AsyncCache; import com.google.common.truth.FailureMetadata; import com.google.common.truth.Subject; @@ -36,9 +39,9 @@ public final class AsyncCacheSubject extends Subject { private final AsyncCache actual; - private AsyncCacheSubject(FailureMetadata metadata, AsyncCache subject) { + private AsyncCacheSubject(FailureMetadata metadata, @Nullable AsyncCache subject) { super(metadata, subject); - this.actual = subject; + this.actual = requireNonNull(subject); } public static Factory> asyncCache() { @@ -81,7 +84,7 @@ public void doesNotContainKey(Object key) { } /** Fails if the cache does not contain the given value. */ - public void containsValue(Object value) { + public void containsValue(@Nullable Object value) { if (value instanceof Future) { check("cache").about(map()).that(actual.asMap()).containsValue(value); } else { @@ -90,7 +93,7 @@ public void containsValue(Object value) { } /** Fails if the cache does not contain the given entry. */ - public void containsEntry(Object key, Object value) { + public void containsEntry(Object key, @Nullable Object value) { if (value instanceof Future) { check("cache").that(actual.asMap()).containsEntry(key, value); } else { diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheContext.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheContext.java index 016c317c0b..26a0d8d8eb 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheContext.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheContext.java @@ -30,6 +30,7 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.function.Function; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import com.github.benmanes.caffeine.cache.AsyncCache; @@ -92,7 +93,6 @@ public final class CacheContext { final TrackingExecutor executor; final ReferenceType keyStrength; final CacheWeigher cacheWeigher; - final Expiry expiry; final Map original; final CacheExpiry expiryType; final Population population; @@ -106,6 +106,8 @@ public final class CacheContext { final Loader loader; final Stats stats; + final @Nullable Expiry expiry; + final boolean isAsyncLoader; CacheBuilder guava; @@ -124,7 +126,7 @@ public final class CacheContext { @Nullable Map absent; - @SuppressWarnings({"PMD.ExcessiveParameterList", "TooManyParameters"}) + @SuppressWarnings({"NullAway.Init", "PMD.ExcessiveParameterList", "TooManyParameters"}) public CacheContext(InitialCapacity initialCapacity, Stats stats, CacheWeigher cacheWeigher, Maximum maximumSize, CacheExpiry expiryType, Expire afterAccess, Expire afterWrite, Expire refresh, ReferenceType keyStrength, ReferenceType valueStrength, @@ -159,7 +161,7 @@ public CacheContext(InitialCapacity initialCapacity, Stats stats, CacheWeigher c this.compute = compute; this.expiryType = expiryType; this.expiryTime = cacheSpec.expiryTime(); - this.expiry = expiryType.createExpiry(expiryTime); + this.expiry = (expiryType == CacheExpiry.DISABLED) ? null : expiryType.createExpiry(expiryTime); } /** Returns a thread local interner for explicit caching. */ @@ -214,16 +216,19 @@ public Population population() { public Int firstKey() { assertWithMessage("Invalid usage of context").that(firstKey).isNotNull(); + requireNonNull(firstKey); return firstKey; } public Int middleKey() { assertWithMessage("Invalid usage of context").that(middleKey).isNotNull(); + requireNonNull(middleKey); return middleKey; } public Int lastKey() { assertWithMessage("Invalid usage of context").that(lastKey).isNotNull(); + requireNonNull(lastKey); return lastKey; } @@ -417,6 +422,7 @@ public boolean expiresVariably() { return (expiryType != CacheExpiry.DISABLED); } + @NullUnmarked public Expiry expiry() { return expiry; } diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheContextSubject.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheContextSubject.java index a61b262db9..099e1646f3 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheContextSubject.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheContextSubject.java @@ -39,6 +39,8 @@ import java.util.function.Function; import java.util.function.ToLongFunction; +import org.jspecify.annotations.Nullable; + import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Policy.CacheEntry; import com.github.benmanes.caffeine.cache.RemovalCause; @@ -65,9 +67,9 @@ public final class CacheContextSubject extends Subject { private final CacheContext actual; - CacheContextSubject(FailureMetadata metadata, CacheContext subject) { + CacheContextSubject(FailureMetadata metadata, @Nullable CacheContext subject) { super(metadata, subject); - this.actual = subject; + this.actual = requireNonNull(subject); } public static Factory context() { @@ -212,9 +214,9 @@ public static final class StatsSubject extends Subject { private final CacheContext actual; private final boolean isDirect; - private StatsSubject(FailureMetadata metadata, CacheContext context) { + private StatsSubject(FailureMetadata metadata, @Nullable CacheContext context) { super(metadata, context); - this.actual = context; + this.actual = requireNonNull(context); this.isDirect = !context.isRecordingStats() || (context.executorType() == CacheExecutor.DIRECT); } @@ -290,6 +292,7 @@ private ListenerSubject(FailureMetadata metadata, CacheContext context, private static Factory factoryOf( RemovalListenerType... removalListenerTypes) { return (metadata, context) -> { + requireNonNull(context); var subject = Arrays.stream(removalListenerTypes) .filter(listener -> listener.isConsumingListener(context)) .collect(toImmutableMap(identity(), listener -> listener.instance(context))); @@ -356,7 +359,7 @@ private WithCause(RemovalCause cause) { } @CanIgnoreReturnValue - public Exclusive contains(Int key, Int value) { + public Exclusive contains(Int key, @Nullable Int value) { return contains(new SimpleEntry<>(key, value)); } 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 69f6cfa86c..d1d5c7e96d 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 @@ -54,6 +54,7 @@ import com.github.benmanes.caffeine.cache.Scheduler; import com.github.benmanes.caffeine.cache.Weigher; import com.github.benmanes.caffeine.cache.testing.RemovalListeners.ConsumingRemovalListener; +import com.github.benmanes.caffeine.cache.testing.Weighers.SkippedWeigher; import com.github.benmanes.caffeine.testing.ConcurrentTestHarness; import com.github.benmanes.caffeine.testing.Int; import com.google.common.collect.Maps; @@ -198,12 +199,18 @@ enum CacheWeigher { VALUE(() -> (key, value) -> Math.abs(((Int) value).intValue())), /** A flag indicating that the entry is weighted by the value's collection size. */ COLLECTION(() -> (key, value) -> ((Collection) value).size()), - /** A flag indicating that the entry's weight is randomly changing. */ + /** + * A flag indicating that the entry's weight is randomly changing and is skipped by automatic + * validation checks. + */ RANDOM(Weighers::random), - /** A flag indicating that the entry's weight records interactions. */ + /** + * A flag indicating that the entry's weight records interactions and is skipped by automatic + * automatic validation checks. + */ @SuppressWarnings("unchecked") MOCKITO(() -> { - Weigher weigher = Mockito.mock(); + SkippedWeigher weigher = Mockito.mock(); when(weigher.weigh(any(), any())).thenReturn(1); return weigher; }); @@ -267,7 +274,7 @@ CacheExpiry[] expiry() default { enum CacheExpiry { DISABLED { @Override public Expiry createExpiry(Expire expiryTime) { - return null; + throw new AssertionError(); } }, MOCKITO { @@ -419,6 +426,7 @@ enum Loader implements CacheLoader { }, /** A loader that always returns null (no mapping). */ NULL { + @SuppressWarnings("NullAway") @Override public Int load(Int key) { return null; } @@ -461,7 +469,9 @@ enum Loader implements CacheLoader { @Override public Int load(Int key) { throw new UnsupportedOperationException(); } - @SuppressWarnings({"PMD.ReturnEmptyCollectionRatherThanNull", "ReturnsNullCollection"}) + + @SuppressWarnings({"NullAway", + "PMD.ReturnEmptyCollectionRatherThanNull", "ReturnsNullCollection"}) @Override public Map loadAll(Set keys) { return null; } diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheSubject.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheSubject.java index 726e299940..694ff3aec3 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheSubject.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheSubject.java @@ -21,10 +21,13 @@ import static com.github.benmanes.caffeine.testing.MapSubject.map; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.truth.Truth.assertAbout; +import static java.util.Objects.requireNonNull; import java.util.Map; import java.util.Objects; +import org.jspecify.annotations.Nullable; + import com.github.benmanes.caffeine.cache.Cache; import com.google.common.testing.GcFinalization; import com.google.common.truth.Correspondence; @@ -44,9 +47,9 @@ public final class CacheSubject extends Subject { private final Cache actual; - CacheSubject(FailureMetadata metadata, Cache subject) { + CacheSubject(FailureMetadata metadata, @Nullable Cache subject) { super(metadata, subject); - this.actual = subject; + this.actual = requireNonNull(subject); } public static Factory> cache() { @@ -104,7 +107,7 @@ public void doesNotContainKey(Object key) { } /** Fails if the cache does not contain the given value. */ - public void containsValue(Object value) { + public void containsValue(@Nullable Object value) { check("cache").about(map()).that(actual.asMap()).containsValue(value); } @@ -114,7 +117,8 @@ public void doesNotContainValue(Object value) { } /** Fails if the cache does not contain the given entry. */ - public void containsEntry(Object key, Object value) { + public void containsEntry(Object key, @Nullable Object value) { + requireNonNull(value); check("cache").that(actual.asMap()) .comparingValuesUsing(EQUALITY) .containsEntry(key, value); @@ -162,8 +166,8 @@ public static final class CleanUpSubject extends Subject { private final Cache actual; - private CleanUpSubject(FailureMetadata metadata, Cache cache) { - super(metadata, cache.asMap()); + private CleanUpSubject(FailureMetadata metadata, @Nullable Cache cache) { + super(metadata, requireNonNull(cache).asMap()); this.actual = cache; } diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/GuavaCacheFromContext.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/GuavaCacheFromContext.java index 712338ba5e..1a6af68282 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/GuavaCacheFromContext.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/GuavaCacheFromContext.java @@ -34,6 +34,8 @@ import java.util.function.BiFunction; import java.util.function.Function; +import org.jspecify.annotations.Nullable; + import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.LoadingCache; import com.github.benmanes.caffeine.cache.Policy; @@ -138,7 +140,8 @@ public static Cache newGuavaCache(CacheContext context) { return castedCache; } - static class GuavaCache implements Cache, Serializable { + @SuppressWarnings("NullAway") + static class GuavaCache implements Cache, Serializable { private static final long serialVersionUID = 1L; private final com.google.common.cache.Cache cache; @@ -146,10 +149,10 @@ static class GuavaCache implements Cache, Serializable { private final boolean canSnapshot; private final Ticker ticker; - transient ConcurrentMap mapView; transient StatsCounter statsCounter; - transient Policy policy; - transient Set keySet; + transient @Nullable ConcurrentMap mapView; + transient @Nullable Policy policy; + transient @Nullable Set keySet; GuavaCache(com.google.common.cache.Cache cache, CacheContext context) { this.canSnapshot = context.expires() || context.refreshes(); @@ -160,12 +163,12 @@ static class GuavaCache implements Cache, Serializable { } @Override - public V getIfPresent(Object key) { + public @Nullable V getIfPresent(Object key) { return cache.getIfPresent(key); } @Override - public V get(K key, Function mappingFunction) { + public @Nullable V get(K key, Function mappingFunction) { requireNonNull(mappingFunction); try { return cache.get(key, () -> { @@ -201,7 +204,7 @@ public Map getAll(Iterable keys, Function found = getAllPresent(keys); + Map found = getAllPresent(keys); Set keysToLoad = Sets.difference(ImmutableSet.copyOf(keys), found.keySet()); if (keysToLoad.isEmpty()) { return found; @@ -494,6 +497,7 @@ static class GuavaLoadingCache extends GuavaCache implements Loading } @Override + @SuppressWarnings("NullAway") public V get(K key) { try { return cache.get(key); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/RemovalListeners.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/RemovalListeners.java index 18a517e025..4f98c8b5a2 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/RemovalListeners.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/RemovalListeners.java @@ -22,6 +22,8 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.RejectedExecutionException; +import org.jspecify.annotations.Nullable; + import com.github.benmanes.caffeine.cache.RemovalCause; import com.github.benmanes.caffeine.cache.RemovalListener; @@ -44,7 +46,7 @@ public static RemovalListener rejecting() { return new RejectingRemovalListener<>(); } - private static void validate(Object key, Object value, RemovalCause cause) { + private static void validate(@Nullable Object key, @Nullable Object value, RemovalCause cause) { if (cause != RemovalCause.COLLECTED) { requireNonNull(key); requireNonNull(value); @@ -60,7 +62,7 @@ public static final class RejectingRemovalListener public int rejected; @Override - public void onRemoval(K key, V value, RemovalCause cause) { + public void onRemoval(@Nullable K key, @Nullable V value, RemovalCause cause) { validate(key, value, cause); if (reject) { @@ -83,7 +85,7 @@ public ConsumingRemovalListener() { } @Override - public void onRemoval(K key, V value, RemovalCause cause) { + public void onRemoval(@Nullable K key, @Nullable V value, RemovalCause cause) { validate(key, value, cause); removed.add(new RemovalNotification<>(key, value, cause)); } diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/Weighers.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/Weighers.java index d1897c0354..b690593398 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/Weighers.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/Weighers.java @@ -42,6 +42,9 @@ public static Weigher random() { return (Weigher) RandomWeigher.INSTANCE; } + /** A marker to instruct the validation to not check the entry's weight for data consistency. */ + public interface SkippedWeigher extends Weigher {} + static final class ConstantWeigher implements Weigher, Serializable { private static final long serialVersionUID = 1L; @@ -57,7 +60,7 @@ static final class ConstantWeigher implements Weigher, Serializable } } - enum RandomWeigher implements Weigher { + enum RandomWeigher implements SkippedWeigher { INSTANCE; @Override public int weigh(Object key, Object value) { diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/eclipse/acceptance/ConcurrentHashMapAcceptanceTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/eclipse/acceptance/ConcurrentHashMapAcceptanceTest.java index e9addaf1a2..780306989a 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/eclipse/acceptance/ConcurrentHashMapAcceptanceTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/eclipse/acceptance/ConcurrentHashMapAcceptanceTest.java @@ -25,6 +25,7 @@ import org.eclipse.collections.impl.list.Interval; import org.eclipse.collections.impl.parallel.ParallelIterate; import org.eclipse.collections.impl.test.Verify; +import org.jspecify.annotations.NullUnmarked; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -35,6 +36,7 @@ * * Ported from Eclipse Collections 11.0. */ +@NullUnmarked @SuppressWarnings("CanIgnoreReturnValueSuggester") public abstract class ConcurrentHashMapAcceptanceTest { private ExecutorService executor; diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/CollectionSubject.java b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/CollectionSubject.java index 8dc625538e..75402a6c8c 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/CollectionSubject.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/CollectionSubject.java @@ -17,6 +17,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.truth.Truth.assertAbout; +import static java.util.Objects.requireNonNull; import java.util.Collection; import java.util.Deque; @@ -25,6 +26,8 @@ import java.util.Queue; import java.util.Set; +import org.jspecify.annotations.Nullable; + import com.google.common.truth.FailureMetadata; import com.google.common.truth.IterableSubject; @@ -36,7 +39,7 @@ public class CollectionSubject extends IterableSubject { private final Collection actual; - public CollectionSubject(FailureMetadata metadata, Collection subject) { + public CollectionSubject(FailureMetadata metadata, @Nullable Collection subject) { super(metadata, subject); this.actual = subject; } @@ -56,6 +59,7 @@ public final void hasSize(long expectedSize) { /** Fails if the collection does not have less than the given size. */ public void hasSizeLessThan(long other) { + requireNonNull(actual); checkArgument(other >= 0, "expectedSize (%s) must be >= 0", other); check("size()").that(actual.size()).isLessThan(Math.toIntExact(other)); } @@ -83,11 +87,13 @@ public void isExhaustivelyEmpty() { } private void checkIterable() { + requireNonNull(actual); check("iterator().hasNext()").that(actual.iterator().hasNext()).isFalse(); } @SuppressWarnings("CollectionToArray") private void checkCollection() { + requireNonNull(actual); check("size()").that(actual).hasSize(0); check("isEmpty()").that(actual).isEmpty(); check("toArray()").that(actual.toArray()).isEmpty(); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/FutureSubject.java b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/FutureSubject.java index d9272f94ed..0c88752773 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/FutureSubject.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/FutureSubject.java @@ -16,11 +16,14 @@ package com.github.benmanes.caffeine.testing; import static com.google.common.truth.Truth.assertAbout; +import static java.util.Objects.requireNonNull; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; +import org.jspecify.annotations.Nullable; + import com.google.common.truth.FailureMetadata; import com.google.common.truth.Subject; import com.google.common.truth.ThrowableSubject; @@ -32,9 +35,9 @@ * @author ben.manes@gmail.com (Ben Manes) */ public final class FutureSubject extends Subject { - private final CompletableFuture actual; + private final @Nullable CompletableFuture actual; - private FutureSubject(FailureMetadata metadata, CompletableFuture subject) { + private FutureSubject(FailureMetadata metadata, @Nullable CompletableFuture subject) { super(metadata, subject); this.actual = subject; } @@ -43,12 +46,13 @@ public static Factory> future() { return FutureSubject::new; } - public static FutureSubject assertThat(CompletableFuture actual) { + public static FutureSubject assertThat(@Nullable CompletableFuture actual) { return assertAbout(future()).that(actual); } /** Fails if the future is not done. */ public void isDone() { + requireNonNull(actual); if (!actual.isDone()) { failWithActual("expected to be done", actual); } @@ -56,6 +60,7 @@ public void isDone() { /** Fails if the future is done. */ public void isNotDone() { + requireNonNull(actual); if (actual.isDone()) { failWithActual("expected to not be done", actual); } @@ -63,6 +68,7 @@ public void isNotDone() { /** Fails if the future is has not completed exceptionally. */ public void hasCompletedExceptionally() { + requireNonNull(actual); if (!actual.isCompletedExceptionally()) { failWithActual("expected to be completed exceptionally", actual.join()); } @@ -70,6 +76,7 @@ public void hasCompletedExceptionally() { /** Fails if the future is not successful with the given value. */ public void succeedsWith(int value) { + requireNonNull(actual); var result = actual.join(); if (result instanceof Int) { check("future").that(result).isEqualTo(Int.valueOf(value)); @@ -79,18 +86,21 @@ public void succeedsWith(int value) { } /** Fails if the future is not successful with the given value. */ - public void succeedsWith(Object value) { + public void succeedsWith(@Nullable Object value) { + requireNonNull(actual); check("future").that(actual.join()).isEqualTo(value); } /** Fails if the future is not successful with a null value. */ public void succeedsWithNull() { + requireNonNull(actual); check("future").that(actual.join()).isNull(); } /** Fails if the future is did not fail with the given join() exception. */ @CanIgnoreReturnValue public ThrowableSubject failsWith(Class clazz) { + requireNonNull(actual); try { failWithActual("join", actual.join()); throw new AssertionError(); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/Int.java b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/Int.java index 89da30ee3d..92ecba261e 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/Int.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/Int.java @@ -16,6 +16,7 @@ package com.github.benmanes.caffeine.testing; import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; import java.io.Serializable; import java.util.ArrayList; @@ -26,6 +27,8 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; +import org.jspecify.annotations.Nullable; + import com.google.errorprone.annotations.Immutable; /** @@ -48,8 +51,8 @@ public final class Int implements Serializable { private final int value; /** Constructs a newly allocated {@code Int} object with the same {@code value}. */ - public Int(Int value) { - this(value.value); + public Int(@Nullable Int value) { + this(requireNonNull(value).value); } /** diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/IntSubject.java b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/IntSubject.java index 9d034d545e..d53e9a0f67 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/IntSubject.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/IntSubject.java @@ -17,6 +17,8 @@ import static com.google.common.truth.Truth.assertAbout; +import org.jspecify.annotations.Nullable; + import com.google.common.truth.FailureMetadata; import com.google.common.truth.Subject; @@ -27,7 +29,7 @@ */ public final class IntSubject extends Subject { - private IntSubject(FailureMetadata metadata, Int subject) { + private IntSubject(FailureMetadata metadata, @Nullable Int subject) { super(metadata, subject); } @@ -35,7 +37,7 @@ public static Factory integer() { return IntSubject::new; } - public static IntSubject assertThat(Int actual) { + public static IntSubject assertThat(@Nullable Int actual) { return assertAbout(integer()).that(actual); } diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/LoggingEvents.java b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/LoggingEvents.java index 4b793c3624..cd1b19bcc3 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/LoggingEvents.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/LoggingEvents.java @@ -25,6 +25,7 @@ import java.util.Objects; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.slf4j.event.Level; import com.github.valfirst.slf4jtest.LoggingEvent; @@ -43,7 +44,8 @@ public final class LoggingEvents extends ForwardingList { private final List> predicates; private final ImmutableList events; - private ImmutableList filteredEvents; + private @Nullable ImmutableList filteredEvents; + private boolean exclusive; private LoggingEvents(Iterable events) { diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/MapSubject.java b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/MapSubject.java index 32c767e4da..bbeb801aaf 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/MapSubject.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/MapSubject.java @@ -18,9 +18,12 @@ import static com.github.benmanes.caffeine.testing.CollectionSubject.collection; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.truth.Truth.assertAbout; +import static java.util.Objects.requireNonNull; import java.util.Map; +import org.jspecify.annotations.Nullable; + import com.google.common.collect.ImmutableSet; import com.google.common.collect.Range; import com.google.common.truth.FailureMetadata; @@ -34,9 +37,9 @@ */ public class MapSubject extends com.google.common.truth.MapSubject { @SuppressWarnings("ImmutableMemberCollection") - private final Map actual; + private final @Nullable Map actual; - public MapSubject(FailureMetadata metadata, Map subject) { + public MapSubject(FailureMetadata metadata, @Nullable Map subject) { super(metadata, subject); this.actual = subject; } @@ -56,6 +59,7 @@ public final void hasSize(long expectedSize) { /** Fails if the map does not have less than the given size. */ public void hasSizeLessThan(long other) { + requireNonNull(actual); checkArgument(other >= 0, "expectedSize (%s) must be >= 0", other); check("size()").that(actual.size()).isLessThan(Math.toIntExact(other)); } @@ -68,17 +72,20 @@ public void hasSizeIn(Range range) { /** Fails if the map does not contain the given keys, where duplicate keys are ignored. */ @CanIgnoreReturnValue public Ordered containsExactlyKeys(Iterable keys) { + requireNonNull(actual); return check("containsKeys").that(actual.keySet()) .containsExactlyElementsIn(ImmutableSet.copyOf(keys)); } /** Fails if the map does not contain the given value. */ - public void containsValue(Object value) { + public void containsValue(@Nullable Object value) { + requireNonNull(actual); check("containsValue").that(actual.values()).contains(value); } /** Fails if the map does contain the given value. */ public void doesNotContainValue(Object value) { + requireNonNull(actual); check("containsValue").that(actual.values()).doesNotContain(value); } @@ -87,6 +94,7 @@ public void doesNotContainValue(Object value) { * methods. */ public void isExhaustivelyEmpty() { + requireNonNull(actual); isEqualTo(Map.of()); hasSize(0); isEmpty(); diff --git a/examples/coalescing-bulkloader-reactor/gradle/libs.versions.toml b/examples/coalescing-bulkloader-reactor/gradle/libs.versions.toml index 8ccad706c3..85ee0daab6 100644 --- a/examples/coalescing-bulkloader-reactor/gradle/libs.versions.toml +++ b/examples/coalescing-bulkloader-reactor/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] caffeine = "3.1.8" junit = "5.11.3" -reactor = "3.7.0" +reactor = "3.7.1" truth = "1.4.4" 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 0cdabcd31b..c085078342 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.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-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 149babf6c3..53023a7268 100644 --- a/examples/coalescing-bulkloader-reactor/settings.gradle.kts +++ b/examples/coalescing-bulkloader-reactor/settings.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("com.gradle.develocity") version "3.18.2" + id("com.gradle.develocity") version "3.19" id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.2" id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } diff --git a/examples/graal-native/gradle/wrapper/gradle-wrapper.properties b/examples/graal-native/gradle/wrapper/gradle-wrapper.properties index 0cdabcd31b..c085078342 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.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-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 a5e4cd278c..1bb26f570f 100644 --- a/examples/graal-native/settings.gradle.kts +++ b/examples/graal-native/settings.gradle.kts @@ -5,7 +5,7 @@ pluginManagement { } } plugins { - id("com.gradle.develocity") version "3.18.2" + id("com.gradle.develocity") version "3.19" id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.2" id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } diff --git a/examples/hibernate/gradle/wrapper/gradle-wrapper.properties b/examples/hibernate/gradle/wrapper/gradle-wrapper.properties index 0cdabcd31b..c085078342 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.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-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 8a0dbec0f9..a6fd48777d 100644 --- a/examples/hibernate/settings.gradle.kts +++ b/examples/hibernate/settings.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("com.gradle.develocity") version "3.18.2" + id("com.gradle.develocity") version "3.19" id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.2" id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } diff --git a/examples/indexable/gradle/wrapper/gradle-wrapper.properties b/examples/indexable/gradle/wrapper/gradle-wrapper.properties index 0cdabcd31b..c085078342 100644 --- a/examples/indexable/gradle/wrapper/gradle-wrapper.properties +++ b/examples/indexable/gradle/wrapper/gradle-wrapper.properties @@ -1,4 +1,4 @@ -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-rc-1-bin.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/examples/indexable/settings.gradle.kts b/examples/indexable/settings.gradle.kts index e17d97cef9..58d363260e 100644 --- a/examples/indexable/settings.gradle.kts +++ b/examples/indexable/settings.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("com.gradle.develocity") version "3.18.2" + id("com.gradle.develocity") version "3.19" id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.2" id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } diff --git a/examples/resilience-failsafe/gradle/wrapper/gradle-wrapper.properties b/examples/resilience-failsafe/gradle/wrapper/gradle-wrapper.properties index 0cdabcd31b..c085078342 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.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-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 0ddb809517..090e9af4ed 100644 --- a/examples/resilience-failsafe/settings.gradle.kts +++ b/examples/resilience-failsafe/settings.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("com.gradle.develocity") version "3.18.2" + id("com.gradle.develocity") version "3.19" id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.2" id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } diff --git a/examples/write-behind-rxjava/gradle/wrapper/gradle-wrapper.properties b/examples/write-behind-rxjava/gradle/wrapper/gradle-wrapper.properties index 0cdabcd31b..c085078342 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.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-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 d04c4ad195..c288943379 100644 --- a/examples/write-behind-rxjava/settings.gradle.kts +++ b/examples/write-behind-rxjava/settings.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("com.gradle.develocity") version "3.18.2" + id("com.gradle.develocity") version "3.19" id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.2" id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fa913b441d..9b51b22ae7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,14 +7,14 @@ bnd = "7.1.0" bouncycastle-jdk18on = "1.79" cache2k = "2.6.1.Final" caffeine = "3.1.8" -checkstyle = "10.20.2" +checkstyle = "10.21.0" coherence = "24.09" commons-collections4 = "4.4" commons-compress = "1.27.1" commons-io = "2.18.0" commons-lang3 = "3.17.0" commons-math3 = "3.6.1" -commons-text = "1.12.0" +commons-text = "1.13.0" concurrentlinkedhashmap = "1.4.2" config = "1.4.3" coveralls = "2.12.2" @@ -32,7 +32,7 @@ felix-scr = "2.2.12" findsecbugs = "1.13.0" flip-tables = "1.1.1" forbidden-apis = "3.8" -google-java-format = "1.25.0" +google-java-format = "1.25.2" guava = "33.3.1-jre" guice = "6.0.0" h2 = "2.3.232" @@ -68,7 +68,7 @@ kotlin = "2.1.0" lincheck = "2.34" mockito = "5.14.2" nexus-publish = "2.0.0" -nullaway = "0.12.1" +nullaway = "0.12.2" nullaway-plugin = "2.1.0" okhttp-bom = "4.12.0" okio-bom = "3.9.1" @@ -85,7 +85,7 @@ slf4j-test = "3.0.1" snakeyaml = "2.3" sonarqube = "6.0.1.5171" spotbugs = "4.8.6" -spotbugs-contrib = "7.6.8" +spotbugs-contrib = "7.6.9" spotbugs-plugin = "6.0.26" stream = "2.9.8" tcache = "2.0.1" diff --git a/gradle/plugins/settings.gradle.kts b/gradle/plugins/settings.gradle.kts index 613c7e28ec..c8e64b1f28 100644 --- a/gradle/plugins/settings.gradle.kts +++ b/gradle/plugins/settings.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("com.gradle.develocity") version "3.18.2" + id("com.gradle.develocity") version "3.19" id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.2" id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } diff --git a/gradle/plugins/src/main/kotlin/quality/errorprone.caffeine.gradle.kts b/gradle/plugins/src/main/kotlin/quality/errorprone.caffeine.gradle.kts index 115c71bedc..a71aa47639 100644 --- a/gradle/plugins/src/main/kotlin/quality/errorprone.caffeine.gradle.kts +++ b/gradle/plugins/src/main/kotlin/quality/errorprone.caffeine.gradle.kts @@ -66,6 +66,8 @@ tasks.withType().configureEach { nullaway { if (name.contains("Test")) { disable() + } else { + error() } annotatedPackages.add("com.github.benmanes.caffeine") annotatedPackages.add("com.google.common") diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0cdabcd31b..c085078342 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.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-rc-1-bin.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/settings.gradle.kts b/settings.gradle.kts index cab1d2d545..451101b3ab 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,9 +2,9 @@ pluginManagement { includeBuild("gradle/plugins") } plugins { - id("com.gradle.develocity") version "3.18.2" + id("com.gradle.develocity") version "3.19" id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.2" - id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" + id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0" } dependencyResolutionManagement {