diff --git a/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/GradleBuildServerProjectImporter.java b/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/GradleBuildServerProjectImporter.java index b018b482b..9cf4c3997 100644 --- a/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/GradleBuildServerProjectImporter.java +++ b/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/GradleBuildServerProjectImporter.java @@ -152,7 +152,11 @@ public boolean applies(Collection projectConfigurations, IProgressMonitor public void importToWorkspace(IProgressMonitor monitor) throws OperationCanceledException, CoreException { IPath rootPath = ResourceUtils.filePathFromURI(rootFolder.toURI().toString()); BuildServerConnection buildServer = ImporterPlugin.getBuildServerConnection(rootPath, true); - + if (buildServer == null) { + JavaLanguageServerPlugin.logError("Reach the maximum number of attempts to connect to the build server, use BuildShip instead"); + this.isResolved = false; + return; + } // for all the path in this.directories, find the out most directory which belongs // to rootFolder and use that directory as the root folder for the build server. // TODO: consider the following folder structure @@ -181,10 +185,9 @@ public void importToWorkspace(IProgressMonitor monitor) throws OperationCanceled buildServer.onBuildInitialized(); // TODO: save the capabilities of this server } catch (CompletionException e) { - Throwable cause = e.getCause(); if (e.getCause() instanceof ResponseErrorException responseError) { if ("Unhandled method build/initialize".equals(responseError.getMessage())) { - JavaLanguageServerPlugin.logException("Failed to start Gradle Build Server, use BuildShip instead", null); + JavaLanguageServerPlugin.logError("Failed to start Gradle Build Server, use BuildShip instead"); this.isResolved = false; return; } diff --git a/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/ImporterPlugin.java b/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/ImporterPlugin.java index 8305ad05f..17e60253f 100644 --- a/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/ImporterPlugin.java +++ b/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/ImporterPlugin.java @@ -1,15 +1,12 @@ package com.microsoft.gradle.bs.importer; -import java.io.File; import java.io.IOException; import java.util.Map; -import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import org.apache.commons.lang3.tuple.Pair; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Plugin; @@ -18,6 +15,7 @@ import org.eclipse.lsp4j.jsonrpc.Launcher; import org.osgi.framework.BundleContext; +import com.microsoft.gradle.bs.importer.model.NamedPipeConnectionException; import com.microsoft.java.builder.BuildStateManager; import ch.epfl.scala.bsp4j.BuildClient; @@ -79,7 +77,7 @@ public static BuildServerConnection getBuildServerConnection(IPath rootPath) thr * Get the build server connection for the given root path. * @param rootPath the root path of the workspace. * @param createIfMissing whether to create a new build server connection if it doesn't exist. - * @return the build server connection. + * @return the build server connection. If fail to connect before max attempt, returns null and fallback to BuildShip. * @throws CoreException */ public static BuildServerConnection getBuildServerConnection(IPath rootPath, boolean createIfMissing) throws CoreException { @@ -114,6 +112,8 @@ public static BuildServerConnection getBuildServerConnection(IPath rootPath, boo client.onConnectWithServer(server); instance.buildServers.put(rootPath, Pair.of(server, client)); return server; + } catch (NamedPipeConnectionException e) { + return null; } catch (IOException e) { throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, "Failed to start build server.", e)); diff --git a/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/NamedPipeStream.java b/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/NamedPipeStream.java index 1b9dd5c05..463567ad2 100644 --- a/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/NamedPipeStream.java +++ b/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/NamedPipeStream.java @@ -19,6 +19,8 @@ import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin; import org.eclipse.core.runtime.Platform; + +import com.microsoft.gradle.bs.importer.model.NamedPipeConnectionException; import com.microsoft.gradle.bs.importer.model.Telemetry; /** @@ -90,7 +92,7 @@ private void initializeNamedPipe() { Utils.sendTelemetry(JavaLanguageServerPlugin.getProjectsManager().getConnection(), telemetry); if (attempts == MAX_ATTEMPTS) { - throw new RuntimeException("Failed to connect to the named pipe after " + MAX_ATTEMPTS + " attempts"); + throw new NamedPipeConnectionException("Failed to connect to extension", MAX_ATTEMPTS); } } diff --git a/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/model/NamedPipeConnectionException.java b/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/model/NamedPipeConnectionException.java new file mode 100644 index 000000000..aa0377f1b --- /dev/null +++ b/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/model/NamedPipeConnectionException.java @@ -0,0 +1,7 @@ +package com.microsoft.gradle.bs.importer.model; + +public class NamedPipeConnectionException extends RuntimeException { + public NamedPipeConnectionException(String message, int maxAttempts) { + super(String.format("%s, Max attempts: %d", message, maxAttempts)); + } +} diff --git a/extension/src/bs/JdtlsImporterConnector.ts b/extension/src/bs/JdtlsImporterConnector.ts index 4806cce3f..a86ff4791 100644 --- a/extension/src/bs/JdtlsImporterConnector.ts +++ b/extension/src/bs/JdtlsImporterConnector.ts @@ -14,11 +14,9 @@ export class JdtlsImporterConnector { private importerConnection: rpc.MessageConnection | null = null; private importerPipeServer: net.Server; private importerPipePath: string; - private readonly context: vscode.ExtensionContext; private readonly _onImporterReady: vscode.EventEmitter = new vscode.EventEmitter(); - constructor(context: vscode.ExtensionContext) { - this.context = context; + constructor(private readonly context: vscode.ExtensionContext) { this.registerCommand(); } @@ -33,6 +31,9 @@ export class JdtlsImporterConnector { return new Promise((resolve) => { this._onImporterReady.event((resolvedPath) => { this.importerPipePath = resolvedPath; + sendInfo("", { + kind: "JdtlsImporterConnectorReceivedPipePath", + }); resolve(); }); });