diff --git a/.github/scripts/analyze.sh b/.github/scripts/analyze.sh index a5c57b7b9d..99418a0d15 100755 --- a/.github/scripts/analyze.sh +++ b/.github/scripts/analyze.sh @@ -2,7 +2,7 @@ set -eux ./gradlew \ - forbiddenApis -DforbiddenApis \ - pmdJavaPoet pmdMain pmdCodeGen pmdJmh -Dpmd \ + forbiddenApis forbiddenApisTest -DforbiddenApis \ + pmdJavaPoet pmdMain pmdCodeGen pmdJmh pmdTest -Dpmd \ spotbugsJavaPoet spotbugsMain spotbugsCodeGen spotbugsJmh -Dspotbugs \ "$@" diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml index f53d51edba..15270c671f 100644 --- a/.github/workflows/analysis.yml +++ b/.github/workflows/analysis.yml @@ -23,7 +23,7 @@ jobs: forbiddenApis: runs-on: ubuntu-latest env: - JAVA_VERSION: 21 + JAVA_VERSION: 22 steps: - name: Harden Runner uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 @@ -36,12 +36,12 @@ jobs: uses: ./.github/actions/run-gradle with: java: ${{ env.JAVA_VERSION }} - arguments: forbiddenApis -DforbiddenApis + arguments: forbiddenApis forbiddenApisTest -DforbiddenApis pmd: runs-on: ubuntu-latest env: - JAVA_VERSION: 22 + JAVA_VERSION: 23 steps: - name: Harden Runner uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 @@ -54,12 +54,12 @@ jobs: uses: ./.github/actions/run-gradle with: java: ${{ env.JAVA_VERSION }} - arguments: pmdJavaPoet pmdMain pmdCodeGen pmdJmh -Dpmd + arguments: pmdJavaPoet pmdMain pmdCodeGen pmdJmh pmdTest -Dpmd spotbugs: runs-on: ubuntu-latest env: - JAVA_VERSION: 22 + JAVA_VERSION: 23 steps: - name: Harden Runner uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cebd5dd5bb..300864425f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,7 +48,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: [ 11, 22, 24, GraalVM ] + java: [ 11, 23, 24, GraalVM ] env: JAVA_VERSION: ${{ matrix.java }} steps: @@ -118,7 +118,7 @@ jobs: - simulator:check - jcache:check - guava:check - java: [ 11, 22 ] + java: [ 11, 23 ] include: - suite: caffeine:weakKeysAndStrongValuesStatsSyncGuavaSlowTest java: 11 diff --git a/.github/workflows/dependency-check.yml b/.github/workflows/dependency-check.yml index ee20b8b6e3..bdc44979af 100644 --- a/.github/workflows/dependency-check.yml +++ b/.github/workflows/dependency-check.yml @@ -8,7 +8,7 @@ permissions: read-all env: DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - JAVA_VERSION: 22 + JAVA_VERSION: 23 jobs: dependency-check: diff --git a/.github/workflows/dependency-submission-pr-retreive.yml b/.github/workflows/dependency-submission-pr-retreive.yml index 2aa03e1240..19861f843b 100644 --- a/.github/workflows/dependency-submission-pr-retreive.yml +++ b/.github/workflows/dependency-submission-pr-retreive.yml @@ -7,7 +7,7 @@ on: env: DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - JAVA_VERSION: 22 + JAVA_VERSION: 23 jobs: submit-dependency-graph: diff --git a/.github/workflows/qodana.yml b/.github/workflows/qodana.yml index bda6efa69d..151931ed95 100644 --- a/.github/workflows/qodana.yml +++ b/.github/workflows/qodana.yml @@ -62,7 +62,7 @@ jobs: java: ${{ env.JAVA_VERSION }} arguments: build -x test - name: Qodana - Code Inspection - uses: JetBrains/qodana-action@c5a69b02e6c1adb092153f7a479169a4b9f3a1cf # v2024.1.9 + uses: JetBrains/qodana-action@5983adcc5fdb505e156e5f756a80f2f979fb1ac0 # v2024.2.2 env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} with: diff --git a/caffeine/build.gradle.kts b/caffeine/build.gradle.kts index 2a1a96bc5c..846d3d374e 100644 --- a/caffeine/build.gradle.kts +++ b/caffeine/build.gradle.kts @@ -299,7 +299,11 @@ for (scenario in Scenario.all()) { if (slow == Slow.Enabled) { maxParallelForks = 2 includeGroups.add("slow") - jvmArgs("-XX:+UseParallelGC") + if (java.toolchain.languageVersion.get().canCompileOrRun(23)) { + jvmArgs("-XX:+UseShenandoahGC") + } else { + jvmArgs("-XX:+UseParallelGC") + } } else { parallel = "methods" excludeGroups("slow", "isolated", "lincheck") diff --git a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/MpscGrowableArrayQueue.java b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/MpscGrowableArrayQueue.java index 2ed0011b45..e52af62c71 100644 --- a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/MpscGrowableArrayQueue.java +++ b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/MpscGrowableArrayQueue.java @@ -63,7 +63,8 @@ protected long getCurrentBufferCapacity(long mask) { } } -@SuppressWarnings({"MultiVariableDeclaration", "OvershadowingSubclassFields"}) +@SuppressWarnings({"MultiVariableDeclaration", + "OvershadowingSubclassFields", "PMD.OneDeclarationPerLine"}) abstract class MpscChunkedArrayQueue extends MpscChunkedArrayQueueColdProducerFields { byte p000, p001, p002, p003, p004, p005, p006, p007; byte p008, p009, p010, p011, p012, p013, p014, p015; @@ -112,7 +113,7 @@ abstract class MpscChunkedArrayQueueColdProducerFields extends BaseMpscLinked } } -@SuppressWarnings("MultiVariableDeclaration") +@SuppressWarnings({"MultiVariableDeclaration", "PMD.OneDeclarationPerLine"}) abstract class BaseMpscLinkedArrayQueuePad1 extends AbstractQueue { byte p000, p001, p002, p003, p004, p005, p006, p007; byte p008, p009, p010, p011, p012, p013, p014, p015; @@ -135,7 +136,8 @@ abstract class BaseMpscLinkedArrayQueueProducerFields extends BaseMpscLinkedA protected long producerIndex; } -@SuppressWarnings({"MultiVariableDeclaration", "OvershadowingSubclassFields"}) +@SuppressWarnings({"MultiVariableDeclaration", + "OvershadowingSubclassFields", "PMD.OneDeclarationPerLine"}) abstract class BaseMpscLinkedArrayQueuePad2 extends BaseMpscLinkedArrayQueueProducerFields { byte p000, p001, p002, p003, p004, p005, p006, p007; byte p008, p009, p010, p011, p012, p013, p014, p015; @@ -161,7 +163,8 @@ abstract class BaseMpscLinkedArrayQueueConsumerFields extends BaseMpscLinkedA protected long consumerIndex; } -@SuppressWarnings({"MultiVariableDeclaration", "OvershadowingSubclassFields"}) +@SuppressWarnings({"MultiVariableDeclaration", + "OvershadowingSubclassFields", "PMD.OneDeclarationPerLine"}) abstract class BaseMpscLinkedArrayQueuePad3 extends BaseMpscLinkedArrayQueueConsumerFields { byte p000, p001, p002, p003, p004, p005, p006, p007; byte p008, p009, p010, p011, p012, p013, p014, p015; 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 b8a6d2cc95..f9f00a7fde 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 @@ -58,7 +58,6 @@ import org.eclipse.collections.impl.factory.Sets; import org.mockito.Mockito; -import org.testng.Assert; import org.testng.annotations.Listeners; import org.testng.annotations.Test; @@ -1009,10 +1008,9 @@ public void computeIfAbsent_recursive(Map map, CacheContext context) { return map.computeIfAbsent(key, this); } }; - try { - map.computeIfAbsent(context.absentKey(), mappingFunction); - Assert.fail(); - } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } + var error = assertThrows(Throwable.class, + () -> map.computeIfAbsent(context.absentKey(), mappingFunction)); + assertThat(error.getClass()).isAnyOf(StackOverflowError.class, IllegalStateException.class); } @CacheSpec @@ -1023,10 +1021,9 @@ public void computeIfAbsent_pingpong(Map map, CacheContext context) { return map.computeIfAbsent(key.negate(), this); } }; - try { - map.computeIfAbsent(context.absentKey(), mappingFunction); - Assert.fail(); - } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } + var error = assertThrows(Throwable.class, + () -> map.computeIfAbsent(context.absentKey(), mappingFunction)); + assertThat(error.getClass()).isAnyOf(StackOverflowError.class, IllegalStateException.class); } @Test(dataProvider = "caches") @@ -1308,10 +1305,9 @@ public void compute_recursive(Map map, CacheContext context) { return map.compute(key, this); } }; - try { - map.compute(context.absentKey(), mappingFunction); - Assert.fail(); - } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } + var error = assertThrows(Throwable.class, + () -> map.compute(context.absentKey(), mappingFunction)); + assertThat(error.getClass()).isAnyOf(StackOverflowError.class, IllegalStateException.class); } @Test(dataProvider = "caches") @@ -1324,20 +1320,15 @@ public void compute_pingpong(Map map, CacheContext context) { return map.compute(key.equals(key1) ? key2 : key1, this); } }; - try { - map.compute(key1, mappingFunction); - Assert.fail(); - } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } + var error = assertThrows(Throwable.class, () -> map.compute(key1, mappingFunction)); + assertThat(error.getClass()).isAnyOf(StackOverflowError.class, IllegalStateException.class); } @CacheSpec @Test(dataProvider = "caches") public void compute_error(Map map, CacheContext context) { - try { - map.compute(context.absentKey(), (key, value) -> { throw new IllegalStateException(); }); - Assert.fail(); - } catch (IllegalStateException e) { /* ignored */ } - + assertThrows(IllegalStateException.class, () -> + map.compute(context.absentKey(), (key, value) -> { throw new IllegalStateException(); })); assertThat(map).isEqualTo(context.original()); assertThat(context).stats().hits(0).misses(0).success(0).failures(1); assertThat(map.compute(context.absentKey(), (k, v) -> intern(k.negate()))) @@ -3095,6 +3086,7 @@ public void writeThroughEntry_equals_hashCode_toString() { assertThat(entry.toString()).isNotEqualTo(other.toString()); } + @SuppressWarnings("PMD.DoNotExtendJavaLangError") static final class ExpectedError extends Error { private static final long serialVersionUID = 1L; } 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 d3f0776323..c1b3b05cd0 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 @@ -55,7 +55,6 @@ import org.eclipse.collections.impl.factory.Sets; import org.mockito.Mockito; -import org.testng.Assert; import org.testng.annotations.Listeners; import org.testng.annotations.Test; @@ -829,10 +828,9 @@ public void computeIfAbsent_recursive(AsyncCache cache, CacheContext c return cache.asMap().computeIfAbsent(key, this); } }; - try { - cache.asMap().computeIfAbsent(context.absentKey(), mappingFunction); - Assert.fail(); - } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } + var error = assertThrows(Throwable.class, + () -> cache.asMap().computeIfAbsent(context.absentKey(), mappingFunction)); + assertThat(error.getClass()).isAnyOf(StackOverflowError.class, IllegalStateException.class); } @CacheSpec @@ -843,10 +841,9 @@ public void computeIfAbsent_pingpong(AsyncCache cache, CacheContext co return cache.asMap().computeIfAbsent(key.negate(), this); } }; - try { - cache.asMap().computeIfAbsent(context.absentKey(), mappingFunction); - Assert.fail(); - } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } + var error = assertThrows(Throwable.class, + () -> cache.asMap().computeIfAbsent(context.absentKey(), mappingFunction)); + assertThat(error.getClass()).isAnyOf(StackOverflowError.class, IllegalStateException.class); } @Test(dataProvider = "caches") @@ -1085,10 +1082,9 @@ public void compute_recursive(AsyncCache cache, CacheContext context) return cache.asMap().compute(key, this); } }; - try { - cache.asMap().compute(context.absentKey(), mappingFunction); - Assert.fail(); - } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } + var error = assertThrows(Throwable.class, + () -> cache.asMap().compute(context.absentKey(), mappingFunction)); + assertThat(error.getClass()).isAnyOf(StackOverflowError.class, IllegalStateException.class); } @Test(dataProvider = "caches") @@ -1101,10 +1097,8 @@ public void compute_pingpong(AsyncCache cache, CacheContext context) { return cache.asMap().compute(key.equals(key1) ? key2 : key1, this); } }; - try { - cache.asMap().compute(key1, mappingFunction); - Assert.fail(); - } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } + var error = assertThrows(Throwable.class, () -> cache.asMap().compute(key1, mappingFunction)); + assertThat(error.getClass()).isAnyOf(StackOverflowError.class, IllegalStateException.class); } @Test(dataProvider = "caches") diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncTest.java index 7c8283f6d9..2a8290ae4a 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncTest.java @@ -45,6 +45,7 @@ public final class AsyncTest { private static final long ONE_MINUTE = TimeUnit.MINUTES.toNanos(1); @Test + @SuppressWarnings("PMD.AvoidAccessibilityAlteration") public void reflectivelyConstruct() throws ReflectiveOperationException { var constructor = Async.class.getDeclaredConstructor(); constructor.setAccessible(true); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/BoundedBufferTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/BoundedBufferTest.java index 79114b8892..ebc45b5bf0 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/BoundedBufferTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/BoundedBufferTest.java @@ -100,6 +100,7 @@ public void overflow() { } @Test + @SuppressWarnings("PMD.AvoidAccessibilityAlteration") public void reflectivelyConstruct() throws ReflectiveOperationException { var constructor = BBHeader.class.getDeclaredConstructor(); constructor.setAccessible(true); 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 0e7b0ae607..c3147e5d70 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 @@ -236,6 +236,7 @@ public void clear_pendingWrites_weakKeys( /* --------------- Maintenance --------------- */ @Test + @SuppressWarnings("PMD.UnusedAssignment") public void cleanupTask_allowGc() { var cache = new BoundedLocalCache( Caffeine.newBuilder(), /* cacheLoader= */ null, /* isAsync= */ false) {}; @@ -2206,7 +2207,7 @@ public void refreshIfNeeded_liveliness(CacheContext context) { // Capture the refresh parameters, should not be retired/dead sentinel entry var refreshEntry = new AtomicReference>(); - var cache = asBoundedLocalCache(context.build(new CacheLoader() { + var cache = asBoundedLocalCache(context.build(new CacheLoader<>() { @Override public Int load(Object key) { throw new AssertionError(); } @@ -2526,6 +2527,7 @@ private static void checkBrokenEqualityMessage( /* --------------- Miscellaneous --------------- */ @Test + @SuppressWarnings("PMD.AvoidAccessibilityAlteration") public void reflectivelyConstruct() throws ReflectiveOperationException { var constructor = BLCHeader.class.getDeclaredConstructor(); constructor.setAccessible(true); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CacheTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CacheTest.java index e9029ee597..2e377de270 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CacheTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CacheTest.java @@ -333,7 +333,8 @@ public void getAllPresent_ordered(Cache cache, CacheContext context) { @Test(dataProvider = "caches") @CacheSpec(population = Population.EMPTY) public void getAllPresent_jdk8186171(Cache cache, CacheContext context) { - class Key { + @SuppressWarnings("PMD.OverrideBothEqualsAndHashcode") + final class Key { @Override public int hashCode() { return 0; // to put keys in one bucket } @@ -582,7 +583,8 @@ public void getAll_present_ordered_exceeds(Cache cache, CacheContext c @Test(dataProvider = "caches") @CacheSpec(population = Population.EMPTY) public void getAll_jdk8186171(CacheContext context) { - class Key { + @SuppressWarnings("PMD.OverrideBothEqualsAndHashcode") + final class Key { @Override public int hashCode() { return 0; // to put keys in one bucket } @@ -942,6 +944,7 @@ public void serialize(Cache cache, CacheContext context) { @CheckNoStats @Test(dataProvider = "caches") + @SuppressWarnings("PMD.AvoidAccessibilityAlteration") @CacheSpec(implementation = Implementation.Caffeine, population = Population.EMPTY) public void readObject(CacheContext context) throws NoSuchMethodException { var cache = context.isAsync() ? context.asyncCache() : context.cache(); 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 96b587e87c..684bcf70f6 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 @@ -33,7 +33,8 @@ * * @author Adam Winer */ -@SuppressWarnings("PreferJavaTimeOverload") +@SuppressWarnings({"PMD.DetachedTestCase", + "PMD.JUnit4TestShouldUseTestAnnotation", "PreferJavaTimeOverload"}) public class CaffeineSpecGuavaTest extends TestCase { public void testParse_empty() { diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CaffeineTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CaffeineTest.java index 2c8fac5015..85e8a45647 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CaffeineTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CaffeineTest.java @@ -205,13 +205,13 @@ public void loading_nullLoader() { @Test public void async_weakValues() { var builder = Caffeine.newBuilder().weakValues(); - assertThrows(IllegalStateException.class, () -> builder.buildAsync()); + assertThrows(IllegalStateException.class, builder::buildAsync); } @Test public void async_softValues() { var builder = Caffeine.newBuilder().softValues(); - assertThrows(IllegalStateException.class, () -> builder.buildAsync()); + assertThrows(IllegalStateException.class, builder::buildAsync); } @Test 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 4aac036b00..ca451325d4 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 @@ -946,9 +946,13 @@ public void merge_update(Cache cache, maximumSize = Maximum.FULL, weigher = CacheWeigher.MOCKITO) public void refresh_weigherFails_absent(LoadingCache cache, CacheContext context) { when(context.weigher().weigh(any(), any())).thenThrow(IllegalStateException.class); - try { - cache.refresh(context.absentKey()).join(); - } catch (IllegalStateException e) { /* ignored */ } + if (context.isAsync()) { + assertThrows(IllegalStateException.class, () -> cache.refresh(context.absentKey()).join()); + } else if (context.isCaffeine()) { + assertThat(cache.refresh(context.absentKey())).succeedsWith(context.absentKey().negate()); + } else { + assertThat(cache.refresh(context.absentKey())).succeedsWithNull(); + } assertThat(cache).doesNotContainKey(context.absentKey()); } @@ -973,10 +977,14 @@ public void refresh_weigherFails_absent_async( @CacheSpec(population = Population.FULL, loader = Loader.IDENTITY, maximumSize = Maximum.FULL, weigher = CacheWeigher.MOCKITO) public void refresh_weigherFails_present(LoadingCache cache, CacheContext context) { + // the refresh's reload is successful but updating the cache fails, is logged, and is discarded when(context.weigher().weigh(any(), any())).thenThrow(IllegalStateException.class); - try { - cache.refresh(context.firstKey()).join(); - } catch (IllegalStateException e) { /* ignored */ } + if (context.isGuava()) { + // an artifact of poor emulation by looking up the current value once completed. + assertThat(cache.refresh(context.firstKey())).succeedsWith(context.firstKey().negate()); + } else { + assertThat(cache.refresh(context.firstKey())).succeedsWith(context.firstKey()); + } assertThat(cache).containsExactlyEntriesIn(context.original()); } diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ExpireAfterVarTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ExpireAfterVarTest.java index 2ef184b4e9..d447b056c6 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ExpireAfterVarTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ExpireAfterVarTest.java @@ -58,7 +58,6 @@ import java.util.function.BiFunction; import org.mockito.Mockito; -import org.testng.Assert; import org.testng.annotations.Listeners; import org.testng.annotations.Test; @@ -1233,10 +1232,9 @@ public void compute_recursive(CacheContext context, VarExpiration expi return expireAfterVar.compute(key, this, Duration.ofDays(1)); } }; - try { - expireAfterVar.compute(context.absentKey(), mappingFunction, Duration.ofDays(1)); - Assert.fail(); - } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } + var error = assertThrows(Throwable.class, () -> + expireAfterVar.compute(context.absentKey(), mappingFunction, Duration.ofDays(1))); + assertThat(error.getClass()).isAnyOf(StackOverflowError.class, IllegalStateException.class); } @Test(dataProvider = "caches") @@ -1250,10 +1248,9 @@ public void compute_pingpong(CacheContext context, VarExpiration expir return expireAfterVar.compute(key.equals(key1) ? key2 : key1, this, Duration.ofDays(1)); } }; - try { - expireAfterVar.compute(key1, mappingFunction, Duration.ofDays(1)); - Assert.fail(); - } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } + var error = assertThrows(Throwable.class, () -> + expireAfterVar.compute(key1, mappingFunction, Duration.ofDays(1))); + assertThat(error.getClass()).isAnyOf(StackOverflowError.class, IllegalStateException.class); } @Test(dataProvider = "caches") diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/InternerTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/InternerTest.java index 1384a56ff9..662caaa84c 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/InternerTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/InternerTest.java @@ -48,6 +48,7 @@ */ public final class InternerTest extends TestCase { + @SuppressWarnings("PMD.JUnit4SuitesShouldUseSuiteAnnotation") public static TestSuite suite() { return SetTestSuiteBuilder .using(new TestStringSetGenerator() { @@ -85,6 +86,7 @@ public void intern(Interner interner) { } @Test + @SuppressWarnings("PMD.UnusedAssignment") public void intern_weak_replace() { var canonical = new Int(1); var other = new Int(1); @@ -102,6 +104,7 @@ public void intern_weak_replace() { } @Test + @SuppressWarnings("PMD.UnusedAssignment") public void intern_weak_remove() { var canonical = new Int(1); var next = new Int(2); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeTest.java index 4f479614d2..20eabf84f2 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeTest.java @@ -45,7 +45,7 @@ * * @author ben.manes@gmail.com (Ben Manes) */ -@SuppressWarnings("ClassEscapesDefinedScope") +@SuppressWarnings({"ClassEscapesDefinedScope", "PMD.LooseCoupling"}) public final class LinkedDequeTest { static final int SIZE = 100; diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeTests.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeTests.java index 662c46b5ca..758696c627 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeTests.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeTests.java @@ -53,14 +53,15 @@ public final class LinkedDequeTests extends TestCase { // cause unexpected mutations. Instead, a different collection type should be used for comparison static final ThreadLocal useTarget = ThreadLocal.withInitial(() -> false); + @SuppressWarnings("PMD.JUnit4SuitesShouldUseSuiteAnnotation") public static Test suite() { var suite = new TestSuite(); - suite.addTest(suite("AccessOrderDeque", AccessOrderDeque::new)); - suite.addTest(suite("WriteOrderDeque", WriteOrderDeque::new)); + suite.addTest(newTestSuite("AccessOrderDeque", AccessOrderDeque::new)); + suite.addTest(newTestSuite("WriteOrderDeque", WriteOrderDeque::new)); return suite; } - static Test suite(String name, Supplier> supplier) { + private static Test newTestSuite(String name, Supplier> supplier) { return QueueTestSuiteBuilder .using(new TestLinkedValueGenerator() { @Override public Queue create(LinkedValue[] elements) { @@ -92,7 +93,7 @@ abstract static class TestLinkedValueGenerator implements TestQueueGenerator samples() { - return new SampleElements(b, a, c, d, e); + return new SampleElements<>(b, a, c, d, e); } @Override diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LoadingCacheTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LoadingCacheTest.java index 3b7864c1fe..96252ab64a 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LoadingCacheTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/LoadingCacheTest.java @@ -427,7 +427,8 @@ public void getAll_present_ordered_exceeds(LoadingCache cache, CacheCo @Test(dataProvider = "caches") @CacheSpec(population = Population.EMPTY) public void getAll_jdk8186171(CacheContext context) { - class Key { + @SuppressWarnings("PMD.OverrideBothEqualsAndHashcode") + final class Key { @Override public int hashCode() { return 0; // to put keys in one bucket } diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/MpscGrowableArrayQueueTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/MpscGrowableArrayQueueTest.java index e2beda0281..290bfc2441 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/MpscGrowableArrayQueueTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/MpscGrowableArrayQueueTest.java @@ -30,7 +30,7 @@ /** * @author ben.manes@gmail.com (Ben Manes) */ -@SuppressWarnings("ClassEscapesDefinedScope") +@SuppressWarnings({"ClassEscapesDefinedScope", "PMD.LooseCoupling"}) public final class MpscGrowableArrayQueueTest { private static final int NUM_PRODUCERS = 10; private static final int PRODUCE = 100; @@ -129,7 +129,7 @@ public void poll_whenPopulated(MpscGrowableArrayQueue queue) { @Test(dataProvider = "full") public void poll_toEmpty(MpscGrowableArrayQueue queue) { - while (queue.poll() != null) {} + while (queue.poll() != null) { /* consume */ } assertThat(queue).isEmpty(); } @@ -146,7 +146,7 @@ public void relaxedPoll_whenPopulated(MpscGrowableArrayQueue queue) { @Test(dataProvider = "full") public void relaxedPoll_toEmpty(MpscGrowableArrayQueue queue) { - while (queue.relaxedPoll() != null) {} + while (queue.relaxedPoll() != null) { /* consume */ } assertThat(queue).isEmpty(); } @@ -224,7 +224,7 @@ public void oneProducer_oneConsumer(MpscGrowableArrayQueue queue) { started.incrementAndGet(); await().untilAtomic(started, is(2)); for (int i = 0; i < PRODUCE; i++) { - while (!queue.offer(i)) {} + while (!queue.offer(i)) { /* produce */ } } finished.incrementAndGet(); }); @@ -232,7 +232,7 @@ public void oneProducer_oneConsumer(MpscGrowableArrayQueue queue) { started.incrementAndGet(); await().untilAtomic(started, is(2)); for (int i = 0; i < PRODUCE; i++) { - while (queue.poll() == null) {} + while (queue.poll() == null) { /* consume */ } } finished.incrementAndGet(); }); @@ -263,7 +263,7 @@ public void manyProducers_oneConsumer(MpscGrowableArrayQueue queue) { started.incrementAndGet(); await().untilAtomic(started, is(NUM_PRODUCERS + 1)); for (int i = 0; i < (NUM_PRODUCERS * PRODUCE); i++) { - while (queue.poll() == null) {} + while (queue.poll() == null) { /* consume */ } } finished.incrementAndGet(); }); @@ -272,7 +272,7 @@ public void manyProducers_oneConsumer(MpscGrowableArrayQueue queue) { started.incrementAndGet(); await().untilAtomic(started, is(NUM_PRODUCERS + 1)); for (int i = 0; i < PRODUCE; i++) { - while (!queue.offer(i)) {} + while (!queue.offer(i)) { /* produce */ } } finished.incrementAndGet(); }); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/MultiThreadedTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/MultiThreadedTest.java index dc92507e0b..37b4045150 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/MultiThreadedTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/MultiThreadedTest.java @@ -63,7 +63,7 @@ public final class MultiThreadedTest { keys = ReferenceType.STRONG, values = ReferenceType.STRONG, evictionListener = Listener.DISABLED) public void concurrent_unbounded(LoadingCache cache, CacheContext context) { - Threads.runTest(cache, operations); + Threads.runTest(cache, operations()); } @Test(dataProvider = "caches") @@ -73,7 +73,7 @@ public void concurrent_unbounded(LoadingCache cache, CacheContext cont keys = ReferenceType.STRONG, values = ReferenceType.STRONG, evictionListener = Listener.DISABLED) public void concurrent_bounded(LoadingCache cache, CacheContext context) { - Threads.runTest(cache, operations); + Threads.runTest(cache, operations()); } @Test(dataProvider = "caches") @@ -85,7 +85,7 @@ public void concurrent_bounded(LoadingCache cache, CacheContext contex evictionListener = Listener.DISABLED) public void async_concurrent_unbounded( AsyncLoadingCache cache, CacheContext context) { - Threads.runTest(cache, asyncOperations); + Threads.runTest(cache, asyncOperations()); } @Test(dataProvider = "caches") @@ -96,76 +96,83 @@ public void async_concurrent_unbounded( evictionListener = Listener.DISABLED) public void async_concurrent_bounded( AsyncLoadingCache cache, CacheContext context) { - Threads.runTest(cache, asyncOperations); + Threads.runTest(cache, asyncOperations()); } @SuppressWarnings({"CollectionToArray", "FutureReturnValueIgnored", "MethodReferenceUsage", - "rawtypes", "ReturnValueIgnored", "SelfEquals", "SizeGreaterThanOrEqualsZero"}) - ImmutableList, Int>> operations = ImmutableList.of( - // LoadingCache - (cache, key) -> { cache.get(key); }, - (cache, key) -> { cache.getAll(List.of(key)); }, - (cache, key) -> { cache.refresh(key); }, + "PMD.OptimizableToArrayCall", "rawtypes", "ReturnValueIgnored", "SelfEquals", + "SizeGreaterThanOrEqualsZero"}) + private static ImmutableList, Int>> operations() { + return ImmutableList.of( + // LoadingCache + (cache, key) -> { cache.get(key); }, + (cache, key) -> { cache.getAll(List.of(key)); }, + (cache, key) -> { cache.refresh(key); }, - // Cache - (cache, key) -> { cache.getIfPresent(key); }, - (cache, key) -> { cache.get(key, identity()); }, - (cache, key) -> { cache.getAllPresent(List.of(key)); }, - (cache, key) -> { cache.put(key, key); }, - (cache, key) -> { cache.putAll(Map.of(key, key)); }, - (cache, key) -> { cache.invalidate(key); }, - (cache, key) -> { cache.invalidateAll(List.of(key)); }, - (cache, key) -> { // expensive so do it less frequently - int random = ThreadLocalRandom.current().nextInt(); - if ((random & 255) == 0) { - cache.invalidateAll(); - } - }, - (cache, key) -> { checkState(cache.estimatedSize() >= 0); }, - (cache, key) -> { cache.stats(); }, - (cache, key) -> { cache.cleanUp(); }, + // Cache + (cache, key) -> { cache.getIfPresent(key); }, + (cache, key) -> { cache.get(key, identity()); }, + (cache, key) -> { cache.getAllPresent(List.of(key)); }, + (cache, key) -> { cache.put(key, key); }, + (cache, key) -> { cache.putAll(Map.of(key, key)); }, + (cache, key) -> { cache.invalidate(key); }, + (cache, key) -> { cache.invalidateAll(List.of(key)); }, + (cache, key) -> { + int random = ThreadLocalRandom.current().nextInt(); + // expensive so do it less frequently + if ((random & 255) == 0) { + cache.invalidateAll(); + } + }, + (cache, key) -> { checkState(cache.estimatedSize() >= 0); }, + (cache, key) -> { cache.stats(); }, + (cache, key) -> { cache.cleanUp(); }, - // Map - (cache, key) -> { cache.asMap().containsKey(key); }, - (cache, key) -> { cache.asMap().containsValue(key); }, - (cache, key) -> { cache.asMap().isEmpty(); }, - (cache, key) -> { checkState(cache.asMap().size() >= 0); }, - (cache, key) -> { cache.asMap().get(key); }, - (cache, key) -> { cache.asMap().put(key, key); }, - (cache, key) -> { cache.asMap().putAll(Map.of(key, key)); }, - (cache, key) -> { cache.asMap().putIfAbsent(key, key); }, - (cache, key) -> { cache.asMap().remove(key); }, - (cache, key) -> { cache.asMap().remove(key, key); }, - (cache, key) -> { cache.asMap().replace(key, key); }, - (cache, key) -> { cache.asMap().computeIfAbsent(key, k -> k); }, - (cache, key) -> { cache.asMap().computeIfPresent(key, (k, v) -> v); }, - (cache, key) -> { cache.asMap().compute(key, (k, v) -> v); }, - (cache, key) -> { cache.asMap().merge(key, key, (k, v) -> v); }, - (cache, key) -> { // expensive so do it less frequently - int random = ThreadLocalRandom.current().nextInt(); - if ((random & 255) == 0) { - cache.asMap().clear(); - } - }, - (cache, key) -> { cache.asMap().keySet().toArray(new Object[cache.asMap().size()]); }, - (cache, key) -> { cache.asMap().values().toArray(new Object[cache.asMap().size()]); }, - (cache, key) -> { cache.asMap().entrySet().toArray(new Map.Entry[cache.asMap().size()]); }, - (cache, key) -> { cache.hashCode(); }, - (cache, key) -> { cache.equals(cache); }, - (cache, key) -> { cache.toString(); }, - (cache, key) -> { // expensive so do it less frequently - int random = ThreadLocalRandom.current().nextInt(); - if ((random & 255) == 0) { - SerializableTester.reserialize(cache); - } - }); + // Map + (cache, key) -> { cache.asMap().containsKey(key); }, + (cache, key) -> { cache.asMap().containsValue(key); }, + (cache, key) -> { cache.asMap().isEmpty(); }, + (cache, key) -> { checkState(cache.asMap().size() >= 0); }, + (cache, key) -> { cache.asMap().get(key); }, + (cache, key) -> { cache.asMap().put(key, key); }, + (cache, key) -> { cache.asMap().putAll(Map.of(key, key)); }, + (cache, key) -> { cache.asMap().putIfAbsent(key, key); }, + (cache, key) -> { cache.asMap().remove(key); }, + (cache, key) -> { cache.asMap().remove(key, key); }, + (cache, key) -> { cache.asMap().replace(key, key); }, + (cache, key) -> { cache.asMap().computeIfAbsent(key, k -> k); }, + (cache, key) -> { cache.asMap().computeIfPresent(key, (k, v) -> v); }, + (cache, key) -> { cache.asMap().compute(key, (k, v) -> v); }, + (cache, key) -> { cache.asMap().merge(key, key, (k, v) -> v); }, + (cache, key) -> { // expensive so do it less frequently + int random = ThreadLocalRandom.current().nextInt(); + if ((random & 255) == 0) { + cache.asMap().clear(); + } + }, + (cache, key) -> { cache.asMap().keySet().toArray(new Object[cache.asMap().size()]); }, + (cache, key) -> { cache.asMap().values().toArray(new Object[cache.asMap().size()]); }, + (cache, key) -> { cache.asMap().entrySet().toArray(new Map.Entry[cache.asMap().size()]); }, + (cache, key) -> { cache.hashCode(); }, + (cache, key) -> { cache.equals(cache); }, + (cache, key) -> { cache.toString(); }, + (cache, key) -> { + int random = ThreadLocalRandom.current().nextInt(); + // expensive so do it less frequently + if ((random & 255) == 0) { + SerializableTester.reserialize(cache); + } + }); + } @SuppressWarnings({"CheckReturnValue", "FutureReturnValueIgnored", "MethodReferenceUsage"}) - ImmutableList, Int>> asyncOperations = ImmutableList.of( - (cache, key) -> { cache.getIfPresent(key); }, - (cache, key) -> { cache.get(key, k -> key); }, - (cache, key) -> { cache.get(key, (k, e) -> CompletableFuture.completedFuture(key)); }, - (cache, key) -> { cache.get(key); }, - (cache, key) -> { cache.getAll(List.of(key)); }, - (cache, key) -> { cache.put(key, CompletableFuture.completedFuture(key)); }); + private static ImmutableList, Int>> asyncOperations() { + return ImmutableList.of( + (cache, key) -> { cache.getIfPresent(key); }, + (cache, key) -> { cache.get(key, k -> key); }, + (cache, key) -> { cache.get(key, (k, e) -> CompletableFuture.completedFuture(key)); }, + (cache, key) -> { cache.get(key); }, + (cache, key) -> { cache.getAll(List.of(key)); }, + (cache, key) -> { cache.put(key, CompletableFuture.completedFuture(key)); }); + } } diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/QueueSanityTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/QueueSanityTest.java index fe2b3b33dd..a755a9e385 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/QueueSanityTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/QueueSanityTest.java @@ -38,7 +38,8 @@ /** * @author nitsanw@yahoo.com (Nitsan Wakart) */ -@SuppressWarnings({"deprecation", "PreferJavaTimeOverload", "ThreadPriorityCheck"}) +@SuppressWarnings({"deprecation", "PMD.AbstractClassWithoutAbstractMethod", + "PreferJavaTimeOverload", "ThreadPriorityCheck"}) public abstract class QueueSanityTest { public static final int SIZE = 8192 * 2; @@ -144,7 +145,7 @@ public void whenOfferItemAndPollItemThenSameInstanceReturnedAndQueueIsEmpty() { assertThat(queue, emptyAndZeroSize()); // Act - Integer e = 1876876; + Integer e = 1_876_876; queue.offer(e); assertFalse(queue.isEmpty()); assertEquals(1, queue.size()); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ReferenceTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ReferenceTest.java index f553ba68b7..b745bf969f 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ReferenceTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/ReferenceTest.java @@ -89,8 +89,9 @@ @Test(groups = "slow", dataProviderClass = CacheProvider.class) public final class ReferenceTest { - // These tests require that the JVM uses -XX:SoftRefLRUPolicyMSPerMB=0 and -XX:+UseParallelGC so - // that soft references can be reliably garbage collected by making them behave as weak + // These tests require that the JVM uses a garbage collection algorithm that strictly honors + // -XX:SoftRefLRUPolicyMSPerMB=0 (-XX:+UseParallelGC until 23; -XX:+UseShenandoahGC onward) + // so that soft references can be reliably garbage collected by making them behave as weak // references. @Test(dataProvider = "caches") @@ -564,6 +565,7 @@ public void containsKey(Map map, CacheContext context) { } @Test(dataProvider = "caches") + @SuppressWarnings("PMD.UnusedAssignment") @CacheSpec(population = Population.FULL, requiresWeakOrSoft = true, expireAfterAccess = Expire.DISABLED, expireAfterWrite = Expire.DISABLED, maximumSize = Maximum.DISABLED, weigher = CacheWeigher.DISABLED, 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 51ee473a39..533d351ef9 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 @@ -220,6 +220,7 @@ private void checkEvictionListener( } } + @SuppressWarnings("PMD.AvoidReassigningParameters") private static Weigher unwrapWeigher(Weigher weigher) { for (;;) { if (weigher instanceof BoundedWeigher) { @@ -232,6 +233,7 @@ private void checkEvictionListener( } } + @SuppressWarnings("PMD.AvoidReassigningParameters") private static Expiry unwrapExpiry(Expiry expiry) { for (;;) { if (expiry instanceof AsyncExpiry) { diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/Reset.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/Reset.java index 1d0a518b8a..68f284b727 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/Reset.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/Reset.java @@ -27,8 +27,8 @@ public final class Reset { static final long PROBE = UnsafeAccess.fieldOffset(Thread.class, "threadLocalRandomProbe"); static final long SEED = UnsafeAccess.fieldOffset(Thread.class, "threadLocalRandomSeed"); + static final int RANDOM_SEED = 1_033_096_058; static final int RANDOM_PROBE = 0x9e3779b9; - static final int RANDOM_SEED = 1033096058; private Reset() {} 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 363708ee14..5864fd7cc3 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 @@ -124,12 +124,14 @@ public void disabledFuture_null() { /* --------------- guarded --------------- */ + @Test public void guardedScheduler_null() { assertThrows(NullPointerException.class, () -> Scheduler.guardedScheduler(null)); } @Test public void guardedScheduler_nullFuture() { + @SuppressWarnings("PMD.CloseResource") ScheduledExecutorService scheduledExecutor = Mockito.mock(); var scheduler = Scheduler.forScheduledExecutorService(scheduledExecutor); Executor executor = Mockito.mock(); @@ -170,6 +172,7 @@ public void scheduledExecutorService_null() { @Test public void scheduledExecutorService_schedule() { + @SuppressWarnings("PMD.CloseResource") ScheduledExecutorService scheduledExecutor = Mockito.mock(); var task = ArgumentCaptor.forClass(Runnable.class); Executor executor = Mockito.mock(); @@ -190,6 +193,7 @@ public void scheduledExecutorService_schedule() { @Test public void scheduledExecutorService_shutdown() { + @SuppressWarnings("PMD.CloseResource") ScheduledExecutorService scheduledExecutor = Mockito.mock(); Executor executor = Mockito.mock(); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/StripedBufferTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/StripedBufferTest.java index 10711c1057..f345f9f82f 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/StripedBufferTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/StripedBufferTest.java @@ -109,14 +109,14 @@ public Object[] providesBuffers() { static final class FakeBuffer extends StripedBuffer { final int result; - int drains = 0; + int drains; FakeBuffer(int result) { this.result = result; } @Override protected Buffer create(E e) { - return new Buffer() { + return new Buffer<>() { @Override public int offer(E e) { return result; } 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 6e54ea2ccf..9e185ad207 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 @@ -59,6 +59,7 @@ import com.google.common.collect.Streams; import it.unimi.dsi.fastutil.longs.LongArrayList; +import it.unimi.dsi.fastutil.longs.LongList; /** * @author ben.manes@gmail.com (Ben Manes) @@ -332,7 +333,7 @@ private void checkTimerWheel(long duration) { } } - private static LongArrayList getTimers(Node sentinel) { + private static LongList getTimers(Node sentinel) { var timers = new LongArrayList(); for (var node = sentinel.getNextInVariableOrder(); node != sentinel; node = node.getNextInVariableOrder()) { @@ -359,9 +360,8 @@ public void reschedule(long clock) { } private void checkEmpty() { - for (int i = 0; i < timerWheel.wheel.length; i++) { - for (int j = 0; j < timerWheel.wheel[i].length; j++) { - var sentinel = timerWheel.wheel[i][j]; + for (var wheel : timerWheel.wheel) { + for (var sentinel : wheel) { assertThat(sentinel.getNextInVariableOrder()).isSameInstanceAs(sentinel); assertThat(sentinel.getPreviousInVariableOrder()).isSameInstanceAs(sentinel); } @@ -465,7 +465,7 @@ public void iterator_hasNext(Iterable> iterable) { } @DataProvider(name = "iterator") - @SuppressWarnings("MethodReferenceUsage") + @SuppressWarnings({"MethodReferenceUsage", "PMD.LambdaCanBeMethodReference"}) public Object[][] providesIterators() { Iterable> descending = () -> timerWheel.descendingIterator(); Iterable> ascending = () -> timerWheel.iterator(); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/MpmcArrayBuffer.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/MpmcArrayBuffer.java index 391137f87e..1a52fff30c 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/MpmcArrayBuffer.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/MpmcArrayBuffer.java @@ -15,13 +15,15 @@ */ package com.github.benmanes.caffeine.cache.buffer; +import org.jctools.queues.MessagePassingQueue; import org.jctools.queues.MpmcArrayQueue; /** * @author ben.manes@gmail.com (Ben Manes) */ final class MpmcArrayBuffer extends ReadBuffer { - final MpmcArrayQueue queue; + final MessagePassingQueue queue; + long reads; MpmcArrayBuffer() { diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/MpscArrayBuffer.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/MpscArrayBuffer.java index 5b3a642ef0..f2186b7302 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/MpscArrayBuffer.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/MpscArrayBuffer.java @@ -20,8 +20,10 @@ /** * @author ben.manes@gmail.com (Ben Manes) */ +@SuppressWarnings("PMD.LooseCoupling") final class MpscArrayBuffer extends ReadBuffer { final MpscArrayQueue queue; + long reads; MpscArrayBuffer() { diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/MpscCompoundBuffer.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/MpscCompoundBuffer.java index 2c3058f356..0d0fea6086 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/MpscCompoundBuffer.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/MpscCompoundBuffer.java @@ -15,13 +15,15 @@ */ package com.github.benmanes.caffeine.cache.buffer; +import org.jctools.queues.MessagePassingQueue; import org.jctools.queues.MpscCompoundQueue; /** * @author ben.manes@gmail.com (Ben Manes) */ final class MpscCompoundBuffer extends ReadBuffer { - final MpscCompoundQueue queue; + final MessagePassingQueue queue; + long reads; MpscCompoundBuffer() { diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/issues/Issue568Test.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/issues/Issue568Test.java index 336ac5c961..c714d7c6b8 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/issues/Issue568Test.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/issues/Issue568Test.java @@ -24,6 +24,7 @@ import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.RemovalCause; import com.github.benmanes.caffeine.testing.ConcurrentTestHarness; +import com.google.common.testing.GcFinalization; /** * Issue #568: Incorrect handling of weak/soft reference caching. @@ -110,7 +111,7 @@ public void resurrect() throws InterruptedException { break; } if (Math.random() < .01) { - System.gc(); + GcFinalization.awaitFullGc(); cache.cleanUp(); } else if ((cache.getIfPresent(key) == null) && !missing.getAndSet(true)) { cache.put(key, new Object()); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/issues/Solr10141Test.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/issues/Solr10141Test.java index d428973fbf..c235a2aa6e 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/issues/Solr10141Test.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/issues/Solr10141Test.java @@ -20,6 +20,7 @@ import static java.util.Locale.US; import java.util.Random; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; @@ -45,7 +46,7 @@ public final class Solr10141Test { static final int maxEntries = blocksInTest / 2; static final int nThreads = 64; - static final int nReads = 10000000; + static final int nReads = 10_000_000; static final int readsPerThread = nReads / nThreads; // odds (1 in N) of the next block operation being on the same block as the previous operation... @@ -78,8 +79,8 @@ public void eviction() { .build(); var lastBlock = new AtomicLong(); - var failed = new AtomicBoolean(); var maxObservedSize = new AtomicLong(); + var failed = new ConcurrentLinkedQueue(); ConcurrentTestHarness.timeTasks(nThreads, new Runnable() { @@ -90,8 +91,7 @@ public void eviction() { test(r); } } catch (Throwable e) { - failed.set(true); - e.printStackTrace(); + failed.add(e); } } @@ -132,14 +132,14 @@ void test(Random r) { + "entries=%,d inserts=%,d removals=%,d hits=%,d maxEntries=%,d maxObservedSize=%,d%n", cache.estimatedSize(), inserts.get(), removals.get(), hits.get(), maxEntries, maxObservedSize.get()); - assertThat(failed.get()).isFalse(); + assertThat(failed).isEmpty(); } @Test public void clear() { var inserts = new AtomicLong(); var removals = new AtomicLong(); - var failed = new AtomicBoolean(); + var failed = new ConcurrentLinkedQueue(); RemovalListener listener = (k, v, removalCause) -> { assertThat(v.key).isEqualTo(k); @@ -164,8 +164,7 @@ public void clear() { test(r); } } catch (Throwable e) { - failed.set(true); - e.printStackTrace(); + failed.add(e); } } @@ -191,7 +190,7 @@ void test(Random r) { cache.asMap().clear(); await().until(() -> inserts.get() == removals.get()); - assertThat(failed.get()).isFalse(); + assertThat(failed).isEmpty(); } static class Val { diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/CacheStatsTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/CacheStatsTest.java index 3bc4d643bc..e4df7b5901 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/CacheStatsTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/CacheStatsTest.java @@ -104,6 +104,7 @@ public void underflow() { assertThat(CacheStats.empty().minus(max)).isEqualTo(CacheStats.empty()); } + @SuppressWarnings("PMD.ExcessiveParameterList") private static void checkStats(CacheStats stats, long requestCount, long hitCount, double hitRate, long missCount, double missRate, long loadSuccessCount, long loadFailureCount, double loadFailureRate, long loadCount, long totalLoadTime, 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 4bd0bf301c..faf0e0543b 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 @@ -124,7 +124,7 @@ public final class CacheContext { @Nullable Map absent; - @SuppressWarnings("TooManyParameters") + @SuppressWarnings({"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, diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheGenerator.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheGenerator.java index e6f83b2627..f16dc19ede 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheGenerator.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/CacheGenerator.java @@ -147,6 +147,7 @@ private static Set filterTypes(Optional type, T[] options) { } /** Returns a new cache context based on the combination. */ + @SuppressWarnings("PMD.UnusedAssignment") private CacheContext newCacheContext(List combination) { int index = 0; return new CacheContext( 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 718f248f41..148facf432 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 @@ -390,7 +390,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()); + MOCKITO(Mockito::mock); private final Supplier> factory; @@ -461,7 +461,7 @@ enum Loader implements CacheLoader { @Override public Int load(Int key) { throw new UnsupportedOperationException(); } - @SuppressWarnings("ReturnsNullCollection") + @SuppressWarnings({"PMD.ReturnEmptyCollectionRatherThanNull", "ReturnsNullCollection"}) @Override public Map loadAll(Set keys) { return null; } @@ -795,7 +795,7 @@ enum CacheScheduler { DISABLED(() -> null), SYSTEM(Scheduler::systemScheduler), THREADED(() -> Scheduler.forScheduledExecutorService(scheduledExecutor)), - MOCKITO(() -> Mockito.mock()); + MOCKITO(Mockito::mock); private final Supplier scheduler; 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 92343ec834..726e299940 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 @@ -121,7 +121,7 @@ public void containsEntry(Object key, Object value) { } /** Fails if the cache contains the given entry. */ - public final void doesNotContainEntry(Object key, Object value) { + public void doesNotContainEntry(Object key, Object value) { check("cache").that(actual.asMap()) .comparingValuesUsing(EQUALITY) .doesNotContainEntry(key, value); @@ -150,10 +150,9 @@ public CleanUpSubject whenCleanedUp() { } private static boolean tolerantEquals(Object o1, Object o2) { - if ((o1 instanceof Integer) && (o2 instanceof Long)) { - return ((Integer) o1).longValue() == ((Long) o2).longValue(); - } else if ((o1 instanceof Long) && (o2 instanceof Integer)) { - return ((Long) o1).longValue() == ((Integer) o2).longValue(); + if (((o1 instanceof Integer) || (o1 instanceof Long)) + && ((o2 instanceof Integer) || (o2 instanceof Long))) { + return ((Number) o1).longValue() == ((Number) o2).longValue(); } return Objects.equals(o1, o2); } 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 9b5f2dfa0f..712338ba5e 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 @@ -68,7 +68,7 @@ /** * @author ben.manes@gmail.com (Ben Manes) */ -@SuppressWarnings("serial") +@SuppressWarnings({"PMD.PreserveStackTrace", "serial"}) public final class GuavaCacheFromContext { private GuavaCacheFromContext() {} private static final ThreadLocal error = new ThreadLocal<>(); @@ -626,6 +626,7 @@ static class SingleLoader extends CacheLoader implements Serializabl } @Override + @SuppressWarnings("PMD.ExceptionAsFlowControl") public V load(K key) throws Exception { try { error.set(null); 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 bcaf14d7ae..18a517e025 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 @@ -75,6 +75,7 @@ public static final class ConsumingRemovalListener implements RemovalListener, Serializable { private static final long serialVersionUID = 1L; + @SuppressWarnings("PMD.LooseCoupling") private final CopyOnWriteArrayList> removed; public ConsumingRemovalListener() { diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/TrackingExecutor.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/TrackingExecutor.java index 22afb1f06b..d9207b1b9a 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/TrackingExecutor.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/TrackingExecutor.java @@ -48,6 +48,7 @@ public TrackingExecutor(ExecutorService executor) { } @Override + @SuppressWarnings("PMD.ExceptionAsFlowControl") public void execute(Runnable command) { try { submitted.incrementAndGet(); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/fuzz/CaffeineSpecFuzzer.java b/caffeine/src/test/java/com/github/benmanes/caffeine/fuzz/CaffeineSpecFuzzer.java index 30f5a411ff..158c31f696 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/fuzz/CaffeineSpecFuzzer.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/fuzz/CaffeineSpecFuzzer.java @@ -27,7 +27,7 @@ public final class CaffeineSpecFuzzer { // These tests require the environment variable JAZZER_FUZZ=1 to try new input arguments @FuzzTest(maxDuration = "5m") - @SuppressWarnings("CheckReturnValue") + @SuppressWarnings({"CheckReturnValue", "PMD.EmptyCatchBlock"}) public void parse(FuzzedDataProvider data) { try { CaffeineSpec.parse(data.consumeRemainingAsString()); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/google/CaffeineMapTests.java b/caffeine/src/test/java/com/github/benmanes/caffeine/google/CaffeineMapTests.java index 1508853e10..33b746faa9 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/google/CaffeineMapTests.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/google/CaffeineMapTests.java @@ -38,6 +38,7 @@ */ public final class CaffeineMapTests extends TestCase { + @SuppressWarnings("PMD.JUnit4SuitesShouldUseSuiteAnnotation") public static Test suite() { var suite = new TestSuite(); new CacheGenerator(cacheSpec()).generate().parallel() 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 46a266ce12..4aefbfa0bb 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 @@ -41,6 +41,7 @@ */ @Param(name = "key", gen = IntGen.class, conf = "1:5") @Param(name = "value", gen = IntGen.class, conf = "1:10") +@SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod") public abstract class AbstractLincheckCacheTest { private final LoadingCache cache; diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/ConcurrentTestHarness.java b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/ConcurrentTestHarness.java index ca196f421d..2ebf38f509 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/ConcurrentTestHarness.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/ConcurrentTestHarness.java @@ -103,7 +103,7 @@ public static TestResult timeTasks(int nThreads, Callable task) { startGate.countDown(); Uninterruptibles.awaitUninterruptibly(endGate); long end = System.nanoTime(); - return new TestResult(end - start, toList(results)); + return new TestResult<>(end - start, toList(results)); } /** 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 28ea542dbc..0d5d293273 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 @@ -38,6 +38,7 @@ * * @author ben.manes@gmail.com (Ben Manes) */ +@SuppressWarnings("PMD.LooseCoupling") public final class LoggingEvents extends ForwardingList { private final List> predicates; private final ImmutableList events; diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/Threads.java b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/Threads.java index 5fe6929fa7..cc5113bdbf 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/testing/Threads.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/testing/Threads.java @@ -67,6 +67,7 @@ public static void runTest(A collection, ImmutableList> o } public static void executeWithTimeOut(Queue failures, Callable task) { + @SuppressWarnings("PMD.CloseResource") var es = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setDaemon(true).build()); try { var future = es.submit(task); diff --git a/gradle/config/pmd/rulesSets-test.xml b/gradle/config/pmd/rulesSets-test.xml new file mode 100644 index 0000000000..2709913655 --- /dev/null +++ b/gradle/config/pmd/rulesSets-test.xml @@ -0,0 +1,140 @@ + + + PMD rules for Caffeine tests + .*/guava/compatibility/.* + .*/eclipse/.* + .*/jsr166/.* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d844b62a49..2d575350b9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ checkstyle = "10.18.1" coherence = "22.06.2" commons-collections4 = "4.4" commons-compress = "1.27.1" -commons-io = "2.16.1" +commons-io = "2.17.0" commons-lang3 = "3.17.0" commons-math3 = "3.6.1" commons-text = "1.12.0" @@ -79,7 +79,7 @@ pax-exam = "4.13.5" pax-url = "2.6.14" picocli = "4.7.6" pmd = "7.5.0" -protobuf = "4.28.1" +protobuf = "4.28.2" slf4j = "2.0.16" slf4j-test = "3.0.1" snakeyaml = "2.3" diff --git a/gradle/plugins/build.gradle.kts b/gradle/plugins/build.gradle.kts index dca051339f..e762cc3309 100644 --- a/gradle/plugins/build.gradle.kts +++ b/gradle/plugins/build.gradle.kts @@ -16,7 +16,7 @@ plugins { alias(libs.plugins.versions) } -java.toolchain.languageVersion = JavaLanguageVersion.of(17) +java.toolchain.languageVersion = JavaLanguageVersion.of(21) dependencies { implementation(libs.jmh) diff --git a/gradle/plugins/src/main/kotlin/lifecycle/publish.caffeine.gradle.kts b/gradle/plugins/src/main/kotlin/lifecycle/publish.caffeine.gradle.kts index 427a95978e..37e2c9ceac 100644 --- a/gradle/plugins/src/main/kotlin/lifecycle/publish.caffeine.gradle.kts +++ b/gradle/plugins/src/main/kotlin/lifecycle/publish.caffeine.gradle.kts @@ -17,7 +17,7 @@ val testJar by tasks.registering(Jar::class) { } val testArtifacts: Configuration by configurations.creating -artifacts.add("testArtifacts", testJar) +artifacts.add(testArtifacts.name, testJar) publishing { publications { 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 df02aed1d5..7245ed8ec4 100644 --- a/gradle/plugins/src/main/kotlin/quality/errorprone.caffeine.gradle.kts +++ b/gradle/plugins/src/main/kotlin/quality/errorprone.caffeine.gradle.kts @@ -1,4 +1,4 @@ -import java.net.URL +import java.net.URI import java.nio.file.Files import java.nio.file.StandardCopyOption.REPLACE_EXISTING import net.ltgt.gradle.errorprone.errorprone @@ -32,9 +32,9 @@ val downloadCaffeine by tasks.registering { doFirst { library.parentFile.mkdirs() - val url = URL("https://repo1.maven.org/maven2/" + val uri = URI.create("https://repo1.maven.org/maven2/" + "com/github/ben-manes/caffeine/caffeine/$version/caffeine-$version.jar") - url.openStream().buffered().use { + uri.toURL().openStream().buffered().use { Files.copy(it, library.toPath(), REPLACE_EXISTING) } } diff --git a/gradle/plugins/src/main/kotlin/quality/pmd.caffeine.gradle.kts b/gradle/plugins/src/main/kotlin/quality/pmd.caffeine.gradle.kts index 7cf9cc06a8..5cb511195a 100644 --- a/gradle/plugins/src/main/kotlin/quality/pmd.caffeine.gradle.kts +++ b/gradle/plugins/src/main/kotlin/quality/pmd.caffeine.gradle.kts @@ -22,3 +22,8 @@ tasks.withType().configureEach { } isConsoleOutput = true } + +tasks.named("pmdTest").configure { + ruleSetConfig = resources.text.fromFile( + rootProject.layout.projectDirectory.file("gradle/config/pmd/rulesSets-test.xml")) +} diff --git a/guava/src/test/java/com/github/benmanes/caffeine/guava/CaffeinatedGuavaTest.java b/guava/src/test/java/com/github/benmanes/caffeine/guava/CaffeinatedGuavaTest.java index 93a75233a7..a6e2b1d2e6 100644 --- a/guava/src/test/java/com/github/benmanes/caffeine/guava/CaffeinatedGuavaTest.java +++ b/guava/src/test/java/com/github/benmanes/caffeine/guava/CaffeinatedGuavaTest.java @@ -17,12 +17,16 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.lang.reflect.Constructor; import java.util.Map; import java.util.Set; import java.util.concurrent.CompletionException; +import org.junit.jupiter.api.Test; + import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.guava.CaffeinatedGuavaLoadingCache.CaffeinatedLoader; import com.github.benmanes.caffeine.guava.CaffeinatedGuavaLoadingCache.ExternalBulkLoader; @@ -43,14 +47,13 @@ import com.google.common.util.concurrent.SettableFuture; import com.google.errorprone.annotations.CanIgnoreReturnValue; -import junit.framework.TestCase; - /** * @author ben.manes@gmail.com (Ben Manes) */ -public final class CaffeinatedGuavaTest extends TestCase { +final class CaffeinatedGuavaTest { - public void testSerializable() { + @Test + void serializable() { SerializableTester.reserialize(CaffeinatedGuava.build(Caffeine.newBuilder())); SerializableTester.reserialize(CaffeinatedGuava.build( Caffeine.newBuilder(), IdentityLoader.INSTANCE)); @@ -58,20 +61,24 @@ public void testSerializable() { Caffeine.newBuilder(), TestingCacheLoaders.identityLoader())); } - public void testReflectivelyConstruct() throws ReflectiveOperationException { + @Test + @SuppressWarnings("PMD.AvoidAccessibilityAlteration") + void reflectivelyConstruct() throws ReflectiveOperationException { Constructor constructor = CaffeinatedGuava.class.getDeclaredConstructor(); constructor.setAccessible(true); constructor.newInstance(); } - public void testHasMethod_notFound() { - assertFalse(CaffeinatedGuava.hasMethod(TestingCacheLoaders.identityLoader(), "abc")); + @Test + void hasMethod_notFound() { + assertThat(CaffeinatedGuava.hasMethod(TestingCacheLoaders.identityLoader(), "abc")).isFalse(); } - public void testReload_interrupted() { + @Test + void reload_interrupted() { LoadingCache cache = CaffeinatedGuava.build( Caffeine.newBuilder().executor(MoreExecutors.directExecutor()), - new CacheLoader() { + new CacheLoader<>() { @Override public Integer load(Integer key) throws InterruptedException { throw new InterruptedException(); } @@ -82,10 +89,11 @@ public void testReload_interrupted() { cache.refresh(1); } - public void testReload_throwable() { + @Test + void reload_throwable() { LoadingCache cache = CaffeinatedGuava.build( Caffeine.newBuilder().executor(MoreExecutors.directExecutor()), - new CacheLoader() { + new CacheLoader<>() { @Override public Integer load(Integer key) throws Exception { throw new Exception(); } @@ -96,7 +104,8 @@ public void testReload_throwable() { cache.refresh(1); } - public void testCacheLoader_null() { + @Test + void cacheLoader_null() { assertThrows(NullPointerException.class, () -> CaffeinatedGuava.caffeinate(null)); var caffeine1 = CaffeinatedGuava.caffeinate(CacheLoader.from(key -> null)); @@ -121,13 +130,14 @@ public ListenableFuture reload(Integer key, Integer oldValue) { assertThat(e2).hasCauseThat().isInstanceOf(InvalidCacheLoadException.class); } - public void testCacheLoader_exception() { + @Test + void cacheLoader_exception() { runCacheLoaderExceptionTest(new InterruptedException()); runCacheLoaderExceptionTest(new RuntimeException()); runCacheLoaderExceptionTest(new Exception()); } - public void runCacheLoaderExceptionTest(Exception error) { + private static void runCacheLoaderExceptionTest(Exception error) { var guava = new CacheLoader() { @Override public Integer load(Integer key) throws Exception { throw error; @@ -149,7 +159,8 @@ public void runCacheLoaderExceptionTest(Exception error) { assertThat(e3).hasCauseThat().isSameInstanceAs(error); } - public void testCacheLoader_single() throws Exception { + @Test + void cacheLoader_single() throws Exception { var error = new Exception(); var guava = new CacheLoader() { @Override public Integer load(Integer key) throws Exception { @@ -164,7 +175,8 @@ public void testCacheLoader_single() throws Exception { checkSingleLoader(error, guava, caffeine); } - public void testCacheLoader_bulk() throws Exception { + @Test + void cacheLoader_bulk() throws Exception { var error = new Exception(); var guava = new CacheLoader() { @Override public Integer load(Integer key) throws Exception { @@ -186,8 +198,8 @@ public void testCacheLoader_bulk() throws Exception { checkBulkLoader(error, caffeine); } - - public void testCacheLoader_reload() throws Exception { + @Test + void cacheLoader_reload() throws Exception { SettableFuture reloader = SettableFuture.create(); var caffeine = CaffeinatedGuava.caffeinate(new CacheLoader() { @Override public Integer load(Integer key) { @@ -206,7 +218,8 @@ public ListenableFuture reload(Integer key, Integer oldValue) { assertThat(future.join()).isEqualTo(3); } - public void testCacheLoader_reloadFailure() throws Exception { + @Test + void cacheLoader_reloadFailure() throws Exception { SettableFuture reloader = SettableFuture.create(); var caffeine = CaffeinatedGuava.caffeinate(new CacheLoader() { @Override public Integer load(Integer key) { @@ -228,6 +241,7 @@ public ListenableFuture reload(Integer key, Integer oldValue) { assertThat(e).hasCauseThat().isSameInstanceAs(error); } + @SuppressWarnings("PMD.SignatureDeclareThrowsException") private static void checkSingleLoader(Exception error, CacheLoader guava, com.github.benmanes.caffeine.cache.CacheLoader caffeine) throws Exception { assertThat(caffeine).isInstanceOf(ExternalSingleLoader.class); @@ -245,6 +259,7 @@ private static void checkSingleLoader(Exception error, CacheLoader caffeine) throws Exception { assertThat(caffeine).isInstanceOf(ExternalBulkLoader.class); diff --git a/guava/src/test/java/com/github/benmanes/caffeine/guava/GuavaMapTests.java b/guava/src/test/java/com/github/benmanes/caffeine/guava/GuavaMapTests.java index ea9914818d..c4c550d06a 100644 --- a/guava/src/test/java/com/github/benmanes/caffeine/guava/GuavaMapTests.java +++ b/guava/src/test/java/com/github/benmanes/caffeine/guava/GuavaMapTests.java @@ -31,6 +31,7 @@ */ public final class GuavaMapTests extends TestCase { + @SuppressWarnings("PMD.JUnit4SuitesShouldUseSuiteAnnotation") public static Test suite() { var suite = new TestSuite(); addGuavaViewTests(suite); diff --git a/guava/src/test/java/com/github/benmanes/caffeine/guava/MapTestFactory.java b/guava/src/test/java/com/github/benmanes/caffeine/guava/MapTestFactory.java index ec4343d3f0..d15fb6095d 100644 --- a/guava/src/test/java/com/github/benmanes/caffeine/guava/MapTestFactory.java +++ b/guava/src/test/java/com/github/benmanes/caffeine/guava/MapTestFactory.java @@ -43,6 +43,7 @@ private MapTestFactory() {} * @param generator the map generator * @return a suite of tests */ + @SuppressWarnings("PMD.JUnit4SuitesShouldUseSuiteAnnotation") public static Test suite(String name, TestMapGenerator generator) { return ConcurrentMapTestSuiteBuilder .using(generator) diff --git a/guava/src/test/java/com/github/benmanes/caffeine/guava/PackageSanityTests.java b/guava/src/test/java/com/github/benmanes/caffeine/guava/PackageSanityTests.java index ca3edc2a1c..7d471ce274 100644 --- a/guava/src/test/java/com/github/benmanes/caffeine/guava/PackageSanityTests.java +++ b/guava/src/test/java/com/github/benmanes/caffeine/guava/PackageSanityTests.java @@ -32,7 +32,7 @@ public PackageSanityTests() { setDefault(CacheLoader.class, key -> key); setDefault(Caffeine.class, Caffeine.newBuilder()); setDefault(com.google.common.cache.CacheLoader.class, - new com.google.common.cache.CacheLoader() { + new com.google.common.cache.CacheLoader<>() { @CanIgnoreReturnValue @Override public Object load(Object key) { return key; diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/AbstractJCacheTest.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/AbstractJCacheTest.java index c658c966a2..4f6871b333 100644 --- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/AbstractJCacheTest.java +++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/AbstractJCacheTest.java @@ -22,8 +22,10 @@ import javax.cache.CacheManager; import javax.cache.Caching; import javax.cache.integration.CacheLoader; +import javax.cache.spi.CachingProvider; import org.checkerframework.checker.nullness.qual.Nullable; +import org.testng.annotations.AfterClass; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; @@ -61,14 +63,15 @@ public abstract class AbstractJCacheTest { protected CaffeineConfiguration jcacheConfiguration; protected LoadingCacheProxy jcacheLoading; protected CacheProxy jcache; + protected CachingProvider cachingProvider; protected CacheManager cacheManager; protected FakeTicker ticker; @BeforeClass(alwaysRun = true) public void beforeClass() { - var provider = Caching.getCachingProvider(CaffeineCachingProvider.class.getName()); - cacheManager = provider.getCacheManager( - provider.getDefaultURI(), provider.getDefaultClassLoader()); + cachingProvider = Caching.getCachingProvider(CaffeineCachingProvider.class.getName()); + cacheManager = cachingProvider.getCacheManager( + cachingProvider.getDefaultURI(), cachingProvider.getDefaultClassLoader()); cacheManager.getCacheNames().forEach(cacheManager::destroyCache); } @@ -87,6 +90,12 @@ public void after() { cacheManager.destroyCache("jcacheLoading"); } + @AfterClass(alwaysRun = true) + public void afterClass() { + cachingProvider.close(); + cacheManager.close(); + } + /** The base configuration used by the test. */ protected abstract CaffeineConfiguration getConfiguration(); @@ -120,7 +129,7 @@ protected CaffeineConfiguration getLoadingConfiguration() { /** The cache loader used by the test. */ protected CacheLoader getCacheLoader() { - return new CacheLoader() { + return new CacheLoader<>() { @CanIgnoreReturnValue @Override public Integer load(Integer key) { return key; diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/CacheManagerTest.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/CacheManagerTest.java index 5f9b3cc797..826c2dcf15 100644 --- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/CacheManagerTest.java +++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/CacheManagerTest.java @@ -19,15 +19,16 @@ import static java.util.Locale.US; import java.lang.management.ManagementFactory; -import java.util.function.Supplier; import javax.cache.Cache; import javax.cache.CacheManager; import javax.cache.Caching; import javax.cache.configuration.CompleteConfiguration; +import javax.cache.spi.CachingProvider; import javax.management.ObjectName; import javax.management.OperationsException; +import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -42,31 +43,47 @@ public final class CacheManagerTest { private static final String PROVIDER_NAME = CaffeineCachingProvider.class.getName(); + private CachingProvider cachingProvider; private CacheManager cacheManager; @BeforeClass public void beforeClass() { - var provider = Caching.getCachingProvider(PROVIDER_NAME); - cacheManager = provider.getCacheManager( - provider.getDefaultURI(), provider.getDefaultClassLoader()); + cachingProvider = Caching.getCachingProvider(PROVIDER_NAME); + cacheManager = cachingProvider.getCacheManager( + cachingProvider.getDefaultURI(), cachingProvider.getDefaultClassLoader()); cacheManager.getCacheNames().forEach(cacheManager::destroyCache); } + @AfterClass + public void afterClass() { + cachingProvider.close(); + cacheManager.close(); + } + @Test public void jmxBeanIsRegistered_createCache() throws OperationsException { - checkConfigurationJmx(() -> cacheManager.createCache("cache-not-in-config-file", + checkConfigurationJmx(cacheManager.createCache("cache-not-in-config-file", TypesafeConfigurator.from(ConfigFactory.load(), "test-cache").orElseThrow())); } @Test public void jmxBeanIsRegistered_getCache() throws OperationsException { - checkConfigurationJmx(() -> cacheManager.getCache("test-cache")); + checkConfigurationJmx(cacheManager.getCache("test-cache")); } - private static void checkConfigurationJmx(Supplier> cacheSupplier) - throws OperationsException { - Cache cache = cacheSupplier.get(); + @Test + public void enableManagement_absent() { + cacheManager.enableManagement("absent", true); + assertThat(cacheManager.getCache("absent")).isNull(); + } + + @Test + public void enableStatistics_absent() { + cacheManager.enableStatistics("absent", true); + assertThat(cacheManager.getCache("absent")).isNull(); + } + private static void checkConfigurationJmx(Cache cache) throws OperationsException { @SuppressWarnings("unchecked") CompleteConfiguration configuration = cache.getConfiguration(CompleteConfiguration.class); assertThat(configuration.isManagementEnabled()).isTrue(); @@ -76,14 +93,4 @@ private static void checkConfigurationJmx(Supplier> cacheSupplier) ManagementFactory.getPlatformMBeanServer().getObjectInstance( new ObjectName(String.format(US, name, cache.getName(), PROVIDER_NAME))); } - - @Test - public void enableManagement_absent() { - cacheManager.enableManagement("absent", true); - } - - @Test - public void enableStatistics_absent() { - cacheManager.enableStatistics("absent", true); - } } diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/JCacheGuiceTest.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/JCacheGuiceTest.java index 252df29cbd..096b3171e7 100644 --- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/JCacheGuiceTest.java +++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/JCacheGuiceTest.java @@ -25,6 +25,7 @@ import javax.cache.configuration.Factory; import javax.cache.configuration.FactoryBuilder; import javax.cache.integration.CacheLoader; +import javax.cache.spi.CachingProvider; import org.jsr107.ri.annotations.DefaultCacheResolverFactory; import org.jsr107.ri.annotations.guice.module.CacheAnnotationsModule; @@ -48,7 +49,9 @@ /** * @author ben.manes@gmail.com (Ben Manes) */ +@SuppressWarnings("PMD.CloseResource") public final class JCacheGuiceTest { + @Inject CachingProvider cachingProvider; @Inject CacheManager cacheManager; @Inject Service service; @@ -61,6 +64,8 @@ public void beforeMethod() { @AfterClass public void afterClass() { TypesafeConfigurator.setFactoryCreator(FactoryBuilder::factoryOf); + cachingProvider.close(); + cacheManager.close(); } @Test @@ -142,6 +147,7 @@ void configureCachingProvider() { cacheManager.getCacheNames().forEach(cacheManager::destroyCache); bind(CacheResolverFactory.class).toInstance(new DefaultCacheResolverFactory(cacheManager)); bind(CacheManager.class).toInstance(cacheManager); + bind(CachingProvider.class).toInstance(provider); } } } diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/JCacheProfiler.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/JCacheProfiler.java index 52dd6878e3..ec7c903d71 100644 --- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/JCacheProfiler.java +++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/JCacheProfiler.java @@ -18,8 +18,8 @@ import static java.util.Locale.US; import static java.util.Objects.requireNonNull; +import java.util.OptionalLong; import java.util.Random; -import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -27,11 +27,12 @@ import javax.cache.Cache; import javax.cache.Caching; -import javax.cache.configuration.MutableConfiguration; +import com.github.benmanes.caffeine.jcache.configuration.CaffeineConfiguration; import com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider; import com.google.common.base.Stopwatch; import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.google.common.util.concurrent.Uninterruptibles; import com.google.errorprone.annotations.CanIgnoreReturnValue; /** @@ -44,23 +45,26 @@ public final class JCacheProfiler { private static final int KEYS = 10_000; private static final boolean READ = true; - private final Cache cache; - private final Executor executor; private final LongAdder count; private final Random random; JCacheProfiler() { random = new Random(); count = new LongAdder(); - var provider = Caching.getCachingProvider(CaffeineCachingProvider.class.getName()); - var cacheManager = provider.getCacheManager( - provider.getDefaultURI(), provider.getDefaultClassLoader()); - cache = cacheManager.createCache("profiler", new MutableConfiguration<>()); - executor = Executors.newCachedThreadPool(new ThreadFactoryBuilder() - .setPriority(Thread.MIN_PRIORITY).setDaemon(true).build()); } public void start() { + var configuration = new CaffeineConfiguration() + .setMaximumSize(OptionalLong.of(KEYS)); + try (var provider = Caching.getCachingProvider(CaffeineCachingProvider.class.getName()); + var cacheManager = provider.getCacheManager( + provider.getDefaultURI(), provider.getDefaultClassLoader()); + var cache = cacheManager.createCache("profiler", configuration)) { + run(cache); + } + } + + private void run(Cache cache) { for (int i = 0; i < KEYS; i++) { cache.put(i, Boolean.TRUE); } @@ -76,9 +80,17 @@ public void start() { } }; - scheduleStatusTask(); - for (int i = 0; i < THREADS; i++) { - executor.execute(task); + @SuppressWarnings("PMD.CloseResource") + var executor = Executors.newCachedThreadPool(new ThreadFactoryBuilder() + .setPriority(Thread.MIN_PRIORITY).setDaemon(true).build()); + try { + scheduleStatusTask(); + for (int i = 0; i < THREADS; i++) { + executor.execute(task); + } + } finally { + executor.shutdown(); + Uninterruptibles.awaitTerminationUninterruptibly(executor); } } diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/OSGiTest.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/OSGiTest.java index eb4ac63cbf..a819931db6 100644 --- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/OSGiTest.java +++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/OSGiTest.java @@ -43,6 +43,8 @@ @RunWith(PaxExam.class) @ExamReactorStrategy(PerMethod.class) public final class OSGiTest { + private static final String PROVIDER_NAME = + "com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider"; @Inject private CachingProvider cachingProvider; @@ -67,11 +69,11 @@ public Option[] config() { @Test public void sanity() { - var provider = Caching.getCachingProvider( - "com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider", - getClass().getClassLoader()); - var cache = provider.getCacheManager().getCache("osgi-cache", String.class, Integer.class); - assertNull(cache.get("a")); + try (var provider = Caching.getCachingProvider(PROVIDER_NAME, getClass().getClassLoader()); + var cacheManager = provider.getCacheManager(); + var cache = cacheManager.getCache("osgi-cache", String.class, Integer.class)) { + assertNull(cache.get("a")); + } } @Test diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/configuration/JCacheConfigurationTest.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/configuration/JCacheConfigurationTest.java index 2ba9f08bd8..a17c4ce457 100644 --- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/configuration/JCacheConfigurationTest.java +++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/configuration/JCacheConfigurationTest.java @@ -18,14 +18,14 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; -import java.util.function.Supplier; - import javax.cache.Cache; import javax.cache.CacheException; import javax.cache.CacheManager; import javax.cache.Caching; import javax.cache.configuration.MutableConfiguration; +import javax.cache.spi.CachingProvider; +import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -39,12 +39,13 @@ public final class JCacheConfigurationTest { private static final String PROVIDER_NAME = CaffeineCachingProvider.class.getName(); private MutableConfiguration cacheConfig; + private CachingProvider cachingProvider; private CacheManager cacheManager; @BeforeClass public void beforeClass() { - var provider = Caching.getCachingProvider(PROVIDER_NAME); - cacheManager = provider.getCacheManager(); + cachingProvider = Caching.getCachingProvider(PROVIDER_NAME); + cacheManager = cachingProvider.getCacheManager(); cacheManager.getCacheNames().forEach(cacheManager::destroyCache); cacheConfig = new MutableConfiguration<>(); @@ -52,6 +53,12 @@ public void beforeClass() { cacheConfig.setStatisticsEnabled(true); } + @AfterClass + public void afterClass() { + cachingProvider.close(); + cacheManager.close(); + } + @Test public void equality() { new EqualsTester() @@ -63,24 +70,18 @@ public void equality() { @Test public void anonymousCache() { - checkConfiguration(() -> - cacheManager.createCache("cache-not-in-config-file", cacheConfig), 500L); - checkConfiguration(() -> - cacheManager.getCache("cache-not-in-config-file", String.class, String.class), 500L); + checkConfiguration(cacheManager.createCache("cache-not-in-config-file", cacheConfig), 500L); + checkConfiguration(cacheManager.getCache( + "cache-not-in-config-file", String.class, String.class), 500L); } @Test public void definedCache() { - assertThrows(CacheException.class, () -> - cacheManager.createCache("test-cache-2", cacheConfig)); - - checkConfiguration(() -> - cacheManager.getCache("test-cache-2", String.class, Integer.class), 1000L); + assertThrows(CacheException.class, () -> cacheManager.createCache("test-cache-2", cacheConfig)); + checkConfiguration(cacheManager.getCache("test-cache-2", String.class, Integer.class), 1000L); } - private static void checkConfiguration(Supplier> cacheSupplier, long expectedValue) { - Cache cache = cacheSupplier.get(); - + private static void checkConfiguration(Cache cache, long expectedValue) { @SuppressWarnings("unchecked") CaffeineConfiguration configuration = cache.getConfiguration(CaffeineConfiguration.class); diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/configuration/TestCacheLoader.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/configuration/TestCacheLoader.java index 2e3e2541ff..613fe9d947 100644 --- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/configuration/TestCacheLoader.java +++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/configuration/TestCacheLoader.java @@ -26,7 +26,7 @@ public final class TestCacheLoader implements CacheLoader { @Override public Integer load(Integer key) { return null; } - @SuppressWarnings("ReturnsNullCollection") + @SuppressWarnings({"PMD.ReturnEmptyCollectionRatherThanNull", "ReturnsNullCollection"}) @Override public Map loadAll(Iterable keys) { return null; } diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/configuration/TypesafeConfigurationTest.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/configuration/TypesafeConfigurationTest.java index e08f478f6b..1ef6198f0c 100644 --- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/configuration/TypesafeConfigurationTest.java +++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/configuration/TypesafeConfigurationTest.java @@ -236,14 +236,15 @@ public void testCache2() { @Test public void getCache() { - Cache cache = Caching.getCachingProvider() - .getCacheManager().getCache("test-cache"); - assertThat(cache).isNotNull(); - - @SuppressWarnings("unchecked") - CaffeineConfiguration config = - cache.getConfiguration(CaffeineConfiguration.class); - checkTestCache(config); + try (Cache cache = Caching.getCachingProvider() + .getCacheManager().getCache("test-cache")) { + assertThat(cache).isNotNull(); + + @SuppressWarnings("unchecked") + CaffeineConfiguration config = + cache.getConfiguration(CaffeineConfiguration.class); + checkTestCache(config); + } } private URI getJarResource(String resourceName) { diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/copy/JavaSerializationCopierTest.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/copy/JavaSerializationCopierTest.java index 3c13572f31..9af31ba263 100644 --- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/copy/JavaSerializationCopierTest.java +++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/copy/JavaSerializationCopierTest.java @@ -89,7 +89,7 @@ public void deserializable_classNotFound() { InputStream in, ClassLoader classLoader) throws IOException { return new ObjectInputStream(in) { @Override protected Class resolveClass(ObjectStreamClass desc) - throws IOException, ClassNotFoundException { + throws ClassNotFoundException { throw new ClassNotFoundException(); } }; diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/issues/Issue1065Test.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/issues/Issue1065Test.java index 637b31f2ea..7fb4ce9696 100644 --- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/issues/Issue1065Test.java +++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/issues/Issue1065Test.java @@ -20,7 +20,6 @@ import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.TimeUnit; @@ -79,7 +78,6 @@ public final class Issue1065Test { Cache fallback; Cache cache; - ExecutorService executor; @BeforeMethod public void before() { @@ -88,37 +86,41 @@ public void before() { cache = provider.getCacheManager().createCache("primary", new MutableConfiguration() .addCacheEntryListenerConfiguration(new MutableCacheEntryListenerConfiguration<>( - FactoryBuilder.factoryOf(new Listener()), FactoryBuilder.factoryOf(event -> true), - /* isOldValueRequired= */ true, /* isSynchronous= */ true)) + FactoryBuilder.factoryOf(new Listener(fallback)), FactoryBuilder.factoryOf( + event -> true), /* isOldValueRequired= */ true, /* isSynchronous= */ true)) .setCacheLoaderFactory(new FactoryBuilder.SingletonFactory<>(new Loader())) .setReadThrough(true)); - executor = Executors.newWorkStealingPool(NUM_THREADS); } @AfterMethod public void after() { - executor.shutdownNow(); fallback.close(); cache.close(); } @Test public void deadlock() throws Exception { - for (int i = 0; i < 500; i++) { - var threads = new ConcurrentLinkedQueue(); - var futures = new CompletableFuture[NUM_THREADS]; - for (int j = 0; j < NUM_THREADS; j++) { - futures[j] = CompletableFuture.runAsync(() -> { - threads.add(Thread.currentThread()); - cache.get("key"); - }, executor); - } - try { - CompletableFuture.allOf(futures).get(1, TimeUnit.SECONDS); - cache.removeAll(); - } catch (TimeoutException e) { - fail(i, threads); + var executor = Executors.newWorkStealingPool(NUM_THREADS); + try { + for (int i = 0; i < 500; i++) { + var threads = new ConcurrentLinkedQueue(); + var futures = new CompletableFuture[NUM_THREADS]; + for (int j = 0; j < NUM_THREADS; j++) { + futures[j] = CompletableFuture.runAsync(() -> { + threads.add(Thread.currentThread()); + cache.get("key"); + }, executor); + } + try { + CompletableFuture.allOf(futures).get(1, TimeUnit.SECONDS); + cache.removeAll(); + } catch (TimeoutException e) { + fail(i, threads); + } } + } finally { + executor.shutdown(); + executor.awaitTermination(1, TimeUnit.MINUTES); } } @@ -133,9 +135,15 @@ private static void fail(int iteration, Collection threads) { throw failure; } - private final class Listener implements CacheEntryCreatedListener, Serializable { + private static final class Listener + implements CacheEntryCreatedListener, Serializable { private static final long serialVersionUID = 1L; + private final transient Cache fallback; + + Listener(Cache fallback) { + this.fallback = fallback; + } @Override public void onCreated( Iterable> events) { events.forEach(event -> fallback.put(event.getKey(), event.getValue())); diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/processor/EntryProcessorTest.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/processor/EntryProcessorTest.java index b86620160e..0acf5843d3 100644 --- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/processor/EntryProcessorTest.java +++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/processor/EntryProcessorTest.java @@ -73,24 +73,24 @@ protected CaffeineConfiguration getConfiguration() { @Test public void reload() { - var value1 = jcache.invoke(KEY_1, EntryProcessorTest::process); + var value1 = jcache.invoke(KEY_1, (entry, arguments) -> process(entry)); assertThat(loads).isEqualTo(1); assertThat(value1).isNull(); ticker.advance(Duration.ofMinutes(1)); - var value2 = jcache.invoke(KEY_1, EntryProcessorTest::process); + var value2 = jcache.invoke(KEY_1, (entry, arguments) -> process(entry)); assertThat(loads).isEqualTo(1); assertThat(value2).isNull(); // Expire the entry ticker.advance(Duration.ofMinutes(5)); - var value3 = jcache.invoke(KEY_1, EntryProcessorTest::process); + var value3 = jcache.invoke(KEY_1, (entry, arguments) -> process(entry)); assertThat(loads).isEqualTo(2); assertThat(value3).isNull(); ticker.advance(Duration.ofMinutes(1)); - var value4 = jcache.invoke(KEY_1, EntryProcessorTest::process); + var value4 = jcache.invoke(KEY_1, (entry, arguments) -> process(entry)); assertThat(loads).isEqualTo(2); assertThat(value4).isNull(); } @@ -98,13 +98,13 @@ public void reload() { @Test public void writeOccursForInitialLoadOfEntry() { map.put(KEY_1, 100); - var value = jcache.invoke(KEY_1, EntryProcessorTest::process); + var value = jcache.invoke(KEY_1, (entry, arguments) -> process(entry)); assertThat(writes).isEqualTo(1); assertThat(loads).isEqualTo(1); assertThat(value).isNull(); } - private static Object process(MutableEntry entry, Object... arguments) { + private static Object process(MutableEntry entry) { var value = 1 + firstNonNull(entry.getValue(), 0); entry.setValue(value); return null; diff --git a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/spi/CaffeineCachingProviderTest.java b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/spi/CaffeineCachingProviderTest.java index 1f04499cde..d6e7307294 100644 --- a/jcache/src/test/java/com/github/benmanes/caffeine/jcache/spi/CaffeineCachingProviderTest.java +++ b/jcache/src/test/java/com/github/benmanes/caffeine/jcache/spi/CaffeineCachingProviderTest.java @@ -117,13 +117,14 @@ public void resources_notFound() { public void osgi_getCache() { try (var provider = new CaffeineCachingProvider()) { provider.isOsgiComponent = true; - var cacheManager = provider.getCacheManager( - provider.getDefaultURI(), provider.getDefaultClassLoader()); - assertThat(cacheManager.getCache("test-cache", Object.class, Object.class)).isNotNull(); - assertThat(cacheManager.getCache("test-cache")).isNotNull(); - - cacheManager.createCache("new-cache", new CaffeineConfiguration<>()); - assertThat(cacheManager.getCache("new-cache")).isNotNull(); + try (var cacheManager = provider.getCacheManager( + provider.getDefaultURI(), provider.getDefaultClassLoader())) { + assertThat(cacheManager.getCache("test-cache", Object.class, Object.class)).isNotNull(); + assertThat(cacheManager.getCache("test-cache")).isNotNull(); + try (var cache = cacheManager.createCache("new-cache", new CaffeineConfiguration<>())) { + assertThat(cacheManager.getCache("new-cache")).isSameInstanceAs(cache); + } + } } }