From 7349d15446b92b64a5a8a47b46ba17f3069eddff Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Thu, 23 Apr 2026 13:03:43 +0000 Subject: [PATCH] fix(intelligence): close ExecutorService via try-with-resources (SonarCloud S2095) The virtual-thread executor was shut down in a finally block, which is architecturally correct but triggers SonarCloud's S2095 blocker bug. Java 19+ ExecutorService implements AutoCloseable; try-with-resources invokes close() which safely shuts down and awaits termination. Each future.get() already has a 5-minute timeout + cancel, so by the time close() runs, tasks are terminal and close() returns promptly. The manual 10s+5s shutdown timing is superseded by AutoCloseable contract. --- .../extractor/LanguageEnricher.java | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/main/java/io/github/randomcodespace/iq/intelligence/extractor/LanguageEnricher.java b/src/main/java/io/github/randomcodespace/iq/intelligence/extractor/LanguageEnricher.java index 928e9eb6..7a2e3f15 100644 --- a/src/main/java/io/github/randomcodespace/iq/intelligence/extractor/LanguageEnricher.java +++ b/src/main/java/io/github/randomcodespace/iq/intelligence/extractor/LanguageEnricher.java @@ -122,8 +122,10 @@ record FileTask(String filePath, List fileNodes, LanguageExtractor ext var edgesAdded = new java.util.concurrent.atomic.AtomicInteger(0); var typeHintsAdded = new java.util.concurrent.atomic.AtomicInteger(0); - var executor = Executors.newVirtualThreadPerTaskExecutor(); - try { + // try-with-resources: ExecutorService#close() handles shutdown + awaitTermination. + // Each future.get() below has its own 5-minute timeout + cancel, so by the time + // close() runs, all tasks are terminal and close() returns promptly. + try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { List> futures = new ArrayList<>(tasks.size()); for (FileTask task : tasks) { futures.add(executor.submit(() -> { @@ -183,19 +185,6 @@ record FileTask(String filePath, List fileNodes, LanguageExtractor ext break; } } - } finally { - executor.shutdown(); - try { - if (!executor.awaitTermination(10, TimeUnit.SECONDS)) { - executor.shutdownNow(); - if (!executor.awaitTermination(5, TimeUnit.SECONDS)) { - log.warn("Language enrichment executor did not terminate cleanly"); - } - } - } catch (InterruptedException e) { - executor.shutdownNow(); - Thread.currentThread().interrupt(); - } } edges.addAll(newEdges);