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 9fdebce672..876a0d4404 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 @@ -19,13 +19,13 @@ import static com.github.benmanes.caffeine.cache.Caffeine.calculateHashMapCapacity; import static com.github.benmanes.caffeine.cache.Caffeine.ceilingPowerOfTwo; import static com.github.benmanes.caffeine.cache.Caffeine.requireArgument; -import static com.github.benmanes.caffeine.cache.Caffeine.requireState; import static com.github.benmanes.caffeine.cache.Caffeine.saturatedToNanos; import static com.github.benmanes.caffeine.cache.LocalLoadingCache.newBulkMappingFunction; import static com.github.benmanes.caffeine.cache.LocalLoadingCache.newMappingFunction; import static com.github.benmanes.caffeine.cache.Node.PROBATION; import static com.github.benmanes.caffeine.cache.Node.PROTECTED; import static com.github.benmanes.caffeine.cache.Node.WINDOW; +import static java.util.Locale.US; import static java.util.Objects.requireNonNull; import static java.util.Spliterator.DISTINCT; import static java.util.Spliterator.IMMUTABLE; @@ -289,21 +289,29 @@ protected BoundedLocalCache(Caffeine builder, } /** Ensures that the node is alive during the map operation. */ - static void requireIsAlive(Object key, Node node) { - requireState(node.isAlive(), "An invalid state was detected that occurs if the key's equals " - + "or hashCode was modified while it resided in the cache. This violation of the Map " - + "contract can lead to non-deterministic behavior (key: %s).", key); + void requireIsAlive(Object key, Node node) { + if (!node.isAlive()) { + throw new IllegalStateException(brokenEqualityMessage(key, node)); + } } /** Logs if the node cannot be found in the map but is still alive. */ - static void logIfAlive(Node node) { + void logIfAlive(Node node) { if (node.isAlive()) { - logger.log(Level.ERROR, "An invalid state was detected that occurs if the key's equals or " - + "hashCode was modified while it resided in the cache. This violation of the Map " - + "contract can lead to non-deterministic behavior (key: {}).", node.getKeyReference()); + String message = brokenEqualityMessage(node.getKeyReference(), node); + logger.log(Level.ERROR, message, new IllegalStateException()); } } + /** Returns the formatted broken equality error message. */ + String brokenEqualityMessage(Object key, Node node) { + return String.format(US, "An invalid state was detected that occurs if the key's equals or " + + "hashCode was modified while it resided in the cache. This violation of the Map " + + "contract can lead to non-deterministic behavior (key: %s, key type: %s, " + + "node type: %s, cache type: %s).", key, key.getClass().getSimpleName(), + node.getClass().getSimpleName(), getClass().getSimpleName()); + } + /* --------------- Shared --------------- */ @Override 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 1b1ba2fc38..0982f95df2 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 @@ -2359,7 +2359,10 @@ public void brokenEquality_eviction(BoundedLocalCache cache, assertThat(cache.estimatedSize()).isEqualTo(1); var event = Iterables.getOnlyElement(TestLoggerFactory.getLoggingEvents()); - assertThat(event.getMessage()).contains("An invalid state was detected"); + assertThat(event.getFormattedMessage()).containsMatch( + "An invalid state was detected.*\\(key: \\d+, key type: MutableInt.*\\)"); + assertThat(event.getThrowable().orElseThrow()) + .isInstanceOf(IllegalStateException.class); assertThat(event.getLevel()).isEqualTo(ERROR); cache.data.clear(); @@ -2387,7 +2390,10 @@ public void brokenEquality_expiration( assertThat(cache.estimatedSize()).isEqualTo(1); var event = Iterables.getOnlyElement(TestLoggerFactory.getLoggingEvents()); - assertThat(event.getMessage()).contains("An invalid state was detected"); + assertThat(event.getFormattedMessage()).containsMatch( + "An invalid state was detected.*\\(key: \\d+, key type: MutableInt.*\\)"); + assertThat(event.getThrowable().orElseThrow()) + .isInstanceOf(IllegalStateException.class); assertThat(event.getLevel()).isEqualTo(ERROR); cache.data.clear(); @@ -2408,7 +2414,10 @@ public void brokenEquality_clear(BoundedLocalCache cache, CacheCont assertThat(cache.estimatedSize()).isEqualTo(1); var event = Iterables.getOnlyElement(TestLoggerFactory.getLoggingEvents()); - assertThat(event.getMessage()).contains("An invalid state was detected"); + assertThat(event.getFormattedMessage()).containsMatch( + "An invalid state was detected.*\\(key: \\d+, key type: MutableInt.*\\)"); + assertThat(event.getThrowable().orElseThrow()) + .isInstanceOf(IllegalStateException.class); assertThat(event.getLevel()).isEqualTo(ERROR); cache.data.clear(); @@ -2490,7 +2499,9 @@ private static void testForBrokenEquality(BoundedLocalCache cac key.decrement(); var e = assertThrows(IllegalStateException.class, () -> task.accept(key)); - assertThat(e).hasMessageThat().contains("An invalid state was detected"); + assertThat(e).hasMessageThat().containsMatch( + "An invalid state was detected.*\\(key: \\d+, key type: MutableInt.*\\)"); + cache.data.clear(); } diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 507e21d4cf..f13f643ab8 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -27,7 +27,7 @@ ext { versions = [ autoValue: '1.10.1', cache2k: '2.6.1.Final', - checkerFramework: '3.32.0', + checkerFramework: '3.33.0', coherence: '22.06.2', commonsCompress: '1.23.0', commonsLang3: '3.12.0', @@ -64,7 +64,7 @@ ext { univocityParsers: '2.9.1', ycsb: '0.17.0', xz: '1.9', - zstd: '1.5.4-2', + zstd: '1.5.5-1', ] testVersions = [ awaitility: '4.2.0', diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2b68fb3111..f749b3a6dc 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.1-rc-2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-rc-3-bin.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME