From 8844e875afbd8cd710685e4ed2b42cec11e81bde Mon Sep 17 00:00:00 2001 From: Jiaaming <2455951489@qq.com> Date: Thu, 1 Aug 2024 13:23:45 +0800 Subject: [PATCH 1/6] Fix: stop start build server when getRandomPipepath return empty --- extension/src/Extension.ts | 1 - extension/src/bs/BspProxy.ts | 4 ++-- extension/src/bs/BuildServerConnector.ts | 6 +++++- extension/src/server/GradleServer.ts | 7 ++++++- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/extension/src/Extension.ts b/extension/src/Extension.ts index 35ce42f95..1a90b71e5 100644 --- a/extension/src/Extension.ts +++ b/extension/src/Extension.ts @@ -260,7 +260,6 @@ export class Extension { }); } const activated = !!(await this.rootProjectsStore.getProjectRoots()).length; - this.bspProxy.prepareToStart(); if (!this.server.isReady()) { await this.server.start(); } diff --git a/extension/src/bs/BspProxy.ts b/extension/src/bs/BspProxy.ts index 9097c3a1c..446bb3de3 100644 --- a/extension/src/bs/BspProxy.ts +++ b/extension/src/bs/BspProxy.ts @@ -24,8 +24,8 @@ export class BspProxy { /** * This function needs to be called before we start Java Gradle Server. */ - public prepareToStart(): void { - this.buildServerConnector.setupBuildServerPipeStream(); + public prepareToStart(): boolean { + return this.buildServerConnector.setupBuildServerPipeStream(); } /** diff --git a/extension/src/bs/BuildServerConnector.ts b/extension/src/bs/BuildServerConnector.ts index 6ee4da153..c62cbdae0 100644 --- a/extension/src/bs/BuildServerConnector.ts +++ b/extension/src/bs/BuildServerConnector.ts @@ -15,8 +15,11 @@ export class BuildServerConnector { * Generates a random pipe name, creates a pipe server and * waiting for the connection from the Java build server. */ - public setupBuildServerPipeStream(): void { + public setupBuildServerPipeStream(): boolean { this.serverPipePath = getRandomPipeName(); + if (this.serverPipePath === "") { + return false; + } this.serverPipeServer = net.createServer((socket: net.Socket) => { this.serverConnection = rpc.createMessageConnection( new rpc.StreamMessageReader(socket), @@ -25,6 +28,7 @@ export class BuildServerConnector { this.serverConnection.listen(); }); this.serverPipeServer.listen(this.serverPipePath); + return true; } public getServerConnection(): rpc.MessageConnection | null { diff --git a/extension/src/server/GradleServer.ts b/extension/src/server/GradleServer.ts index bcff565b4..edcbb0078 100644 --- a/extension/src/server/GradleServer.ts +++ b/extension/src/server/GradleServer.ts @@ -49,6 +49,12 @@ export class GradleServer { return this.languageServerPipePath; } public async start(): Promise { + const isPrepared = this.bspProxy.prepareToStart(); + if (!isPrepared) { + this.logger.error("Failed to generate build server pipe path, build server will not start"); + } + const startBuildServer = isPrepared && redHatJavaInstalled() ? "true" : "false"; + this.taskServerPort = await getPort(); const cwd = this.context.asAbsolutePath("lib"); const cmd = path.join(cwd, getGradleServerCommand()); @@ -61,7 +67,6 @@ export class GradleServer { await vscode.window.showErrorMessage(NO_JAVA_EXECUTABLE); return; } - const startBuildServer = redHatJavaInstalled() ? "true" : "false"; const args = [ quoteArg(`--port=${this.taskServerPort}`), quoteArg(`--startBuildServer=${startBuildServer}`), From 504d9655b9e1cb34b55fdc3e0933ac1ab6f43621 Mon Sep 17 00:00:00 2001 From: Jiaaming <2455951489@qq.com> Date: Fri, 2 Aug 2024 14:59:11 +0800 Subject: [PATCH 2/6] Fix: handle build server start issue on Java side --- .vscode/launch.json | 3 +- .../GradleBuildServerProjectImporter.java | 24 +++++++++-- extension/src/bs/BspProxy.ts | 40 +++++++++++++------ extension/src/server/GradleServer.ts | 9 ++++- 4 files changed, 56 insertions(+), 20 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 52a4da376..a33d85730 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -18,7 +18,8 @@ "order": 1 }, "env": { - "DEBUG_VSCODE_JAVA":"true" + "DEBUG_VSCODE_JAVA":"true", + "DEBUG_START_BUILD_SERVER": "true" }, }, { 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 4f19b409b..dd62bc37b 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 @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.CompletionException; import org.eclipse.core.internal.resources.Project; import org.eclipse.core.internal.resources.ProjectDescription; @@ -31,6 +32,8 @@ import org.eclipse.jdt.ls.core.internal.managers.BasicFileDetector; import org.eclipse.jdt.ls.core.internal.managers.DigestStore; import org.eclipse.jdt.ls.core.internal.preferences.Preferences; +import org.eclipse.lsp4j.jsonrpc.ResponseErrorException; + import com.microsoft.java.builder.JavaProblemChecker; import com.microsoft.gradle.bs.importer.model.BuildServerPreferences; import com.microsoft.gradle.bs.importer.model.Telemetry; @@ -54,6 +57,7 @@ public class GradleBuildServerProjectImporter extends AbstractProjectImporter { public static final String SETTINGS_GRADLE_DESCRIPTOR = "settings.gradle"; public static final String SETTINGS_GRADLE_KTS_DESCRIPTOR = "settings.gradle.kts"; public static final String ANDROID_MANIFEST = "AndroidManifest.xml"; + private boolean IS_RESOLVED = true; @Override public boolean applies(IProgressMonitor monitor) throws OperationCanceledException, CoreException { @@ -172,9 +176,21 @@ public void importToWorkspace(IProgressMonitor monitor) throws OperationCanceled ); BuildServerPreferences data = getBuildServerPreferences(); params.setData(data); - InitializeBuildResult initializeResult = buildServer.buildInitialize(params).join(); - buildServer.onBuildInitialized(); - // TODO: save the capabilities of this server + try { + InitializeBuildResult initializeResult = buildServer.buildInitialize(params).join(); + buildServer.onBuildInitialized(); + // TODO: save the capabilities of this server + } catch (CompletionException e) { + Throwable cause = e.getCause(); + if (cause instanceof ResponseErrorException) { + ResponseErrorException responseError = (ResponseErrorException) cause; + if ("Unhandled method build/initialize".equals(responseError.getMessage())) { + JavaLanguageServerPlugin.logException("Failed to start Gradle Build Server, use BuildShip instead", null); + this.IS_RESOLVED = false; + return; + } + } + } if (monitor.isCanceled()) { return; @@ -208,7 +224,7 @@ public boolean isResolved(File folder) throws OperationCanceledException, CoreEx // the gradle project has already imported by other importers, we can modify this logic // so that Maven importer can be involved for other projects. for (IProject project : ProjectUtils.getAllProjects()) { - if (Utils.isGradleBuildServerProject(project) && + if (this.IS_RESOLVED && Utils.isGradleBuildServerProject(project) && project.getLocation().toPath().startsWith(folder.toPath())) { return true; } diff --git a/extension/src/bs/BspProxy.ts b/extension/src/bs/BspProxy.ts index 446bb3de3..089fd7a83 100644 --- a/extension/src/bs/BspProxy.ts +++ b/extension/src/bs/BspProxy.ts @@ -16,6 +16,7 @@ import { sendInfo } from "vscode-extension-telemetry-wrapper"; export class BspProxy { private buildServerConnector: BuildServerConnector; private jdtlsImporterConnector: JdtlsImporterConnector; + private buildServerStart: boolean; constructor(context: vscode.ExtensionContext, private readonly logger: Logger) { this.buildServerConnector = new BuildServerConnector(); @@ -37,11 +38,12 @@ export class BspProxy { public async start(): Promise { await this.jdtlsImporterConnector.waitForImporterPipePath(); await this.jdtlsImporterConnector.setupImporterPipeStream(); - - this.setupMessageForwarding( - this.jdtlsImporterConnector.getImporterConnection(), - this.buildServerConnector.getServerConnection() - ); + if (this.buildServerStart) { + this.setupMessageForwarding( + this.jdtlsImporterConnector.getImporterConnection(), + this.buildServerConnector.getServerConnection() + ); + } this.jdtlsImporterConnector.startListening(); } @@ -53,20 +55,28 @@ export class BspProxy { importerConnection: rpc.MessageConnection | null, buildServerConnection: rpc.MessageConnection | null ): void { - importerConnection?.onRequest((method, params) => { + if (!importerConnection) { + this.logger.error("Failed to setup importer message forwarding"); + return; + } + if (!buildServerConnection) { + this.logger.error("Failed to setup build server message forwarding"); + return; + } + importerConnection.onRequest((method, params) => { if (params !== null) { - return buildServerConnection?.sendRequest(method, params); + return buildServerConnection.sendRequest(method, params); } - return buildServerConnection?.sendRequest(method); + return buildServerConnection.sendRequest(method); }); - buildServerConnection?.onNotification((method, params) => { + buildServerConnection.onNotification((method, params) => { if (params !== null) { - return importerConnection?.sendNotification(method, params); + return importerConnection.sendNotification(method, params); } - importerConnection?.sendNotification(method); + importerConnection.sendNotification(method); }); - importerConnection?.onError(([error]) => { + importerConnection.onError(([error]) => { this.logger.error(`Error on importerConnection: ${error.message}`); sendInfo("", { kind: "bspProxy-importerConnectionError", @@ -76,7 +86,7 @@ export class BspProxy { // TODO: Implement more specific error handling logic here }); - buildServerConnection?.onError(([error]) => { + buildServerConnection.onError(([error]) => { this.logger.error(`Error on buildServerConnection: ${error.message}`); sendInfo("", { kind: "bspProxy-buildServerConnectionError", @@ -86,4 +96,8 @@ export class BspProxy { // TODO: Implement more specific error handling logic here }); } + + public setBuildServerStarted(started: boolean): void { + this.buildServerStart = started; + } } diff --git a/extension/src/server/GradleServer.ts b/extension/src/server/GradleServer.ts index edcbb0078..1a2aeb486 100644 --- a/extension/src/server/GradleServer.ts +++ b/extension/src/server/GradleServer.ts @@ -53,7 +53,12 @@ export class GradleServer { if (!isPrepared) { this.logger.error("Failed to generate build server pipe path, build server will not start"); } - const startBuildServer = isPrepared && redHatJavaInstalled() ? "true" : "false"; + let startBuildServer = isPrepared && redHatJavaInstalled(); + if (process.env.DEBUG_VSCODE_JAVA) { + const debugBuildServer = process.env.DEBUG_START_BUILD_SERVER === "true"; + startBuildServer = startBuildServer && debugBuildServer; + } + this.bspProxy.setBuildServerStarted(startBuildServer); this.taskServerPort = await getPort(); const cwd = this.context.asAbsolutePath("lib"); @@ -72,7 +77,7 @@ export class GradleServer { quoteArg(`--startBuildServer=${startBuildServer}`), quoteArg(`--languageServerPipePath=${this.languageServerPipePath}`), ]; - if (startBuildServer === "true") { + if (startBuildServer) { const buildServerPipeName = this.bspProxy.getBuildServerPipeName(); args.push(quoteArg(`--pipeName=${buildServerPipeName}`)); args.push(quoteArg(`--bundleDir=${bundleDirectory}`)); From e39d79481f633419cb95fa48aedfa77dfb68b34d Mon Sep 17 00:00:00 2001 From: Jiaaming <2455951489@qq.com> Date: Fri, 2 Aug 2024 16:33:52 +0800 Subject: [PATCH 3/6] Fix: comments --- .vscode/launch.json | 1 - .../bs/importer/GradleBuildServerProjectImporter.java | 9 ++++----- extension/src/bs/BspProxy.ts | 2 -- extension/src/server/GradleServer.ts | 6 +----- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index a33d85730..78cdf519c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -19,7 +19,6 @@ }, "env": { "DEBUG_VSCODE_JAVA":"true", - "DEBUG_START_BUILD_SERVER": "true" }, }, { 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 dd62bc37b..b7f0f88b5 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 @@ -57,7 +57,7 @@ public class GradleBuildServerProjectImporter extends AbstractProjectImporter { public static final String SETTINGS_GRADLE_DESCRIPTOR = "settings.gradle"; public static final String SETTINGS_GRADLE_KTS_DESCRIPTOR = "settings.gradle.kts"; public static final String ANDROID_MANIFEST = "AndroidManifest.xml"; - private boolean IS_RESOLVED = true; + private boolean isResolved = true; @Override public boolean applies(IProgressMonitor monitor) throws OperationCanceledException, CoreException { @@ -182,11 +182,10 @@ public void importToWorkspace(IProgressMonitor monitor) throws OperationCanceled // TODO: save the capabilities of this server } catch (CompletionException e) { Throwable cause = e.getCause(); - if (cause instanceof ResponseErrorException) { - ResponseErrorException responseError = (ResponseErrorException) cause; + 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); - this.IS_RESOLVED = false; + this.isResolved = false; return; } } @@ -224,7 +223,7 @@ public boolean isResolved(File folder) throws OperationCanceledException, CoreEx // the gradle project has already imported by other importers, we can modify this logic // so that Maven importer can be involved for other projects. for (IProject project : ProjectUtils.getAllProjects()) { - if (this.IS_RESOLVED && Utils.isGradleBuildServerProject(project) && + if (this.isResolved && Utils.isGradleBuildServerProject(project) && project.getLocation().toPath().startsWith(folder.toPath())) { return true; } diff --git a/extension/src/bs/BspProxy.ts b/extension/src/bs/BspProxy.ts index 233a71607..1f1d69d38 100644 --- a/extension/src/bs/BspProxy.ts +++ b/extension/src/bs/BspProxy.ts @@ -56,11 +56,9 @@ export class BspProxy { buildServerConnection: rpc.MessageConnection | null ): void { if (!importerConnection) { - this.logger.error("Failed to setup importer message forwarding"); return; } if (!buildServerConnection) { - this.logger.error("Failed to setup build server message forwarding"); return; } importerConnection.onRequest((method, params) => { diff --git a/extension/src/server/GradleServer.ts b/extension/src/server/GradleServer.ts index f07f9ea3f..f6ba5c50d 100644 --- a/extension/src/server/GradleServer.ts +++ b/extension/src/server/GradleServer.ts @@ -53,11 +53,7 @@ export class GradleServer { if (!isPrepared) { this.logger.error("Failed to generate build server pipe path, build server will not start"); } - let startBuildServer = isPrepared && redHatJavaInstalled(); - if (process.env.DEBUG_VSCODE_JAVA) { - const debugBuildServer = process.env.DEBUG_START_BUILD_SERVER === "true"; - startBuildServer = startBuildServer && debugBuildServer; - } + const startBuildServer = isPrepared && redHatJavaInstalled(); this.bspProxy.setBuildServerStarted(startBuildServer); this.taskServerPort = await getPort(); From 50128b8287b7e9518457acf934849f228c6d6f79 Mon Sep 17 00:00:00 2001 From: Jiaaming <2455951489@qq.com> Date: Fri, 2 Aug 2024 16:35:02 +0800 Subject: [PATCH 4/6] fix: type --- .vscode/launch.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 78cdf519c..52a4da376 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -18,7 +18,7 @@ "order": 1 }, "env": { - "DEBUG_VSCODE_JAVA":"true", + "DEBUG_VSCODE_JAVA":"true" }, }, { From 175c8b98093d80c6e25959f005f399c78a8aadfa Mon Sep 17 00:00:00 2001 From: Jiaaming <2455951489@qq.com> Date: Fri, 2 Aug 2024 16:50:35 +0800 Subject: [PATCH 5/6] fix: comments --- extension/src/bs/BspProxy.ts | 5 +---- extension/src/server/GradleServer.ts | 13 +++++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/extension/src/bs/BspProxy.ts b/extension/src/bs/BspProxy.ts index 1f1d69d38..1c518814d 100644 --- a/extension/src/bs/BspProxy.ts +++ b/extension/src/bs/BspProxy.ts @@ -55,10 +55,7 @@ export class BspProxy { importerConnection: rpc.MessageConnection | null, buildServerConnection: rpc.MessageConnection | null ): void { - if (!importerConnection) { - return; - } - if (!buildServerConnection) { + if (!importerConnection || !buildServerConnection) { return; } importerConnection.onRequest((method, params) => { diff --git a/extension/src/server/GradleServer.ts b/extension/src/server/GradleServer.ts index f6ba5c50d..823e5397e 100644 --- a/extension/src/server/GradleServer.ts +++ b/extension/src/server/GradleServer.ts @@ -49,11 +49,16 @@ export class GradleServer { return this.languageServerPipePath; } public async start(): Promise { - const isPrepared = this.bspProxy.prepareToStart(); - if (!isPrepared) { - this.logger.error("Failed to generate build server pipe path, build server will not start"); + let startBuildServer = false; + if (redHatJavaInstalled()) { + const isPrepared = this.bspProxy.prepareToStart(); + if (isPrepared) { + startBuildServer = true; + } else { + this.logger.error("Failed to generate build server pipe path, build server will not start"); + } } - const startBuildServer = isPrepared && redHatJavaInstalled(); + this.bspProxy.setBuildServerStarted(startBuildServer); this.taskServerPort = await getPort(); From 644de05dd36e4b4a49692ef1c3c69003cf46303c Mon Sep 17 00:00:00 2001 From: Jiaaming <2455951489@qq.com> Date: Fri, 2 Aug 2024 16:59:40 +0800 Subject: [PATCH 6/6] fix: comments --- .../gradle/bs/importer/GradleBuildServerProjectImporter.java | 5 ++++- extension/src/server/GradleServer.ts | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) 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 b7f0f88b5..b018b482b 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 @@ -222,8 +222,11 @@ public boolean isResolved(File folder) throws OperationCanceledException, CoreEx // TOOD: Once the upstream GradleProjectImporter has been updated to not import when // the gradle project has already imported by other importers, we can modify this logic // so that Maven importer can be involved for other projects. + if (!this.isResolved){ + return false; + } for (IProject project : ProjectUtils.getAllProjects()) { - if (this.isResolved && Utils.isGradleBuildServerProject(project) && + if (Utils.isGradleBuildServerProject(project) && project.getLocation().toPath().startsWith(folder.toPath())) { return true; } diff --git a/extension/src/server/GradleServer.ts b/extension/src/server/GradleServer.ts index 823e5397e..3bc2675ae 100644 --- a/extension/src/server/GradleServer.ts +++ b/extension/src/server/GradleServer.ts @@ -58,7 +58,6 @@ export class GradleServer { this.logger.error("Failed to generate build server pipe path, build server will not start"); } } - this.bspProxy.setBuildServerStarted(startBuildServer); this.taskServerPort = await getPort();