From ecb6ebc571dea0b9a2c968b1996a4280aa8ba84b Mon Sep 17 00:00:00 2001 From: Andreas Hufler Date: Fri, 27 Mar 2026 15:49:03 +0100 Subject: [PATCH 1/3] fix memory leak --- .../toolbox/reflection/util/ClassScannerUtil.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/it/aboutbits/springboot/toolbox/reflection/util/ClassScannerUtil.java b/src/main/java/it/aboutbits/springboot/toolbox/reflection/util/ClassScannerUtil.java index 9bcd0fc..e9ea1aa 100644 --- a/src/main/java/it/aboutbits/springboot/toolbox/reflection/util/ClassScannerUtil.java +++ b/src/main/java/it/aboutbits/springboot/toolbox/reflection/util/ClassScannerUtil.java @@ -6,16 +6,24 @@ import org.jspecify.annotations.NullMarked; import java.lang.annotation.Annotation; +import java.util.Arrays; +import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @NullMarked public final class ClassScannerUtil { + private static final Map CACHE = new ConcurrentHashMap<>(); + private ClassScannerUtil() { } public static ClassScanner getScannerForPackages(String... packages) { - return new ClassScanner(packages); + var cacheKey = Arrays.stream(packages) + .sorted() + .collect(Collectors.joining("|")); + return CACHE.computeIfAbsent(cacheKey, _ -> new ClassScanner(packages)); } public static final class ClassScanner implements AutoCloseable { @@ -54,7 +62,7 @@ public Set> getClassesAnnotatedWith(Class clazz) @Override public void close() { - scanResult.close(); + // No-op: this scanner is cached and its lifecycle is managed by ClassScannerUtil. } } } From a073f8b6b323bfda658713a0340497b0053b5f00 Mon Sep 17 00:00:00 2001 From: AboutBits Tech Date: Fri, 27 Mar 2026 14:53:11 +0000 Subject: [PATCH 2/3] 2.4.2-RC1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a9f4f38..5b15e24 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ it.aboutbits spring-boot-toolbox - 2.4.1 + 2.4.2-RC1 Utility library for Spring Boot projects. jar From a547ba988301b7912e2a4bd475f3afa5821a4b89 Mon Sep 17 00:00:00 2001 From: Andreas Hufler Date: Thu, 9 Apr 2026 08:51:15 +0200 Subject: [PATCH 3/3] remove misleading auto-closeable --- .../toolbox/reflection/util/ClassScannerUtil.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/it/aboutbits/springboot/toolbox/reflection/util/ClassScannerUtil.java b/src/main/java/it/aboutbits/springboot/toolbox/reflection/util/ClassScannerUtil.java index e9ea1aa..195feb7 100644 --- a/src/main/java/it/aboutbits/springboot/toolbox/reflection/util/ClassScannerUtil.java +++ b/src/main/java/it/aboutbits/springboot/toolbox/reflection/util/ClassScannerUtil.java @@ -26,7 +26,7 @@ public static ClassScanner getScannerForPackages(String... packages) { return CACHE.computeIfAbsent(cacheKey, _ -> new ClassScanner(packages)); } - public static final class ClassScanner implements AutoCloseable { + public static final class ClassScanner { private final ScanResult scanResult; private final String[] packages; @@ -59,10 +59,5 @@ public Set> getClassesAnnotatedWith(Class clazz) ClassInfo::loadClass ).collect(Collectors.toSet()); } - - @Override - public void close() { - // No-op: this scanner is cached and its lifecycle is managed by ClassScannerUtil. - } } }