diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/CompilationUnitCache.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/CompilationUnitCache.java index a99deea8f..4567e22d6 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/CompilationUnitCache.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/CompilationUnitCache.java @@ -18,6 +18,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -238,8 +239,9 @@ public final class CompilationUnitCache implements DocumentContentProvider { } private synchronized CompletableFuture requestCU(IJavaProject project, URI uri) throws ExecutionException { - return uriToCu.get(uri, () -> { - CompletableFuture future = CompletableFuture.supplyAsync(() -> { + CompletableFuture cuFuture = uriToCu.getIfPresent(uri); + if (cuFuture == null) { + cuFuture = CompletableFuture.supplyAsync(() -> { try { logger.info("Started parsing CU for " + uri); @@ -252,17 +254,25 @@ public final class CompilationUnitCache implements DocumentContentProvider { logger.info("Parsed successfully CU for " + uri); return cUnit; - } catch (Exception e) { - logger.warn("exception happened during parsing CU for " + uri + ": " + e); - return null; + } catch (Throwable t) { + // Complete future exceptionally + throw new CompletionException(t); } }, createCuExecutorThreadPool); - return future; - - }); + // Cache the future + uriToCu.put(uri, cuFuture); + // If CU future completed exceptionally invalidate the cache entry + cuFuture.exceptionally(t -> { + if (!(t instanceof CancellationException)) { + logger.error("", t); + } + uriToCu.invalidate(uri); + return null; + }); + } + return cuFuture; } - public static CompilationUnit parse2(char[] source, String docURI, String unitName, IJavaProject project) throws Exception { List classpaths = createClasspath(getClasspathEntries(project)); return parse2(source, docURI, unitName, classpaths, null);