diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java index 07820ebf1..3c7ca13c7 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java @@ -26,6 +26,8 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import org.eclipse.lsp4j.ApplyWorkspaceEditParams; @@ -107,6 +109,9 @@ public final class SimpleLanguageServer implements Sts4LanguageServer, LanguageC private static final Scheduler RECONCILER_SCHEDULER = Schedulers.newSingle("Reconciler"); + private static final int FORCED_EXIT_CODE = 1; + private static final int FORCED_EXIT_DELAY_IN_SECONDS = 3; + public final String EXTENSION_ID; private final String CODE_ACTION_COMMAND_ID; public final LazyCompletionResolver completionResolver = createCompletionResolver(); @@ -474,18 +479,36 @@ public final class SimpleLanguageServer implements Sts4LanguageServer, LanguageC @Override public CompletableFuture shutdown() { - return async.invoke(() -> { - Runnable h = shutdownHandler; - if (h!=null) { - h.run(); + log.info("shutdown: request arrived"); + + // make sure the JVM gets the exit call after some time + Executors.newSingleThreadScheduledExecutor().schedule(() -> { + log.info("Forcing exit after 3 sec."); + System.exit(FORCED_EXIT_CODE); + }, FORCED_EXIT_DELAY_IN_SECONDS, TimeUnit.SECONDS); + + // proceed with regular shutdown activities + try { + Runnable h = shutdownHandler; + if (h != null) { + log.info("shutdown: call shutdown handler"); + h.run(); + } + + getWorkspaceService().dispose(); } - getWorkspaceService().dispose(); - return "OK"; - }); + catch (Exception e) { + log.info("problem calling shutdown handlers: ", e); + } + + log.info("shutdown: complete"); + + return CompletableFuture.completedFuture("OK"); } @Override public void exit() { + log.info("exit: notification received"); System.exit(0); } diff --git a/headless-services/commons/language-server-starter/src/main/java/org/springframework/ide/vscode/languageserver/starter/LanguageServerAutoConf.java b/headless-services/commons/language-server-starter/src/main/java/org/springframework/ide/vscode/languageserver/starter/LanguageServerAutoConf.java index 9e5deb968..56e09da87 100644 --- a/headless-services/commons/language-server-starter/src/main/java/org/springframework/ide/vscode/languageserver/starter/LanguageServerAutoConf.java +++ b/headless-services/commons/language-server-starter/src/main/java/org/springframework/ide/vscode/languageserver/starter/LanguageServerAutoConf.java @@ -43,7 +43,8 @@ import com.google.common.collect.ImmutableMap; public class LanguageServerAutoConf { @ConditionalOnMissingBean - @Bean public SimpleLanguageServer languageServer( + @Bean(destroyMethod = "") + public SimpleLanguageServer languageServer( LanguageServerProperties props, Optional severities, Optional completionFilter,