From b7cc2606eca0701b0213a2093108d96819f0e469 Mon Sep 17 00:00:00 2001 From: Jiaaming <2455951489@qq.com> Date: Tue, 23 Jul 2024 09:44:51 +0800 Subject: [PATCH 1/6] merge language server to Gradle server --- .vscode/launch.json | 35 --- extension/src/Extension.ts | 8 +- .../src/languageServer/languageServer.ts | 53 +---- extension/src/server/GradleServer.ts | 6 +- gradle-language-server/build.gradle | 18 +- .../gradle/GradleLanguageServer.java | 17 +- .../gradle/utils/NamedPipeStream.java | 210 ++++++++++++++++++ gradle-server/build.gradle | 6 + .../github/badsyntax/gradle/GradleServer.java | 14 ++ 9 files changed, 263 insertions(+), 104 deletions(-) create mode 100644 gradle-language-server/src/main/java/com/microsoft/gradle/utils/NamedPipeStream.java diff --git a/.vscode/launch.json b/.vscode/launch.json index 97080c446..f24dfdf37 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -77,41 +77,6 @@ "order": 3 } }, - { - "name": "Debug Language Server: Launch Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}/extension" - ], - "outFiles": [ - "${workspaceFolder}/extension/dist/**/*.js" - ], - "preLaunchTask": "Gradle: Build", - "env": { - "VSCODE_DEBUG_LANGUAGE_SERVER": "true", - "VSCODE_GRADLE_PORT": "6006" - }, - "presentation": { - "group": "debug", - "order": 4 - } - }, - { - "type": "java", - "name": "Debug Language Server: Launch Language Server", - "request": "launch", - "mainClass": "com.microsoft.gradle.GradleLanguageServer", - "projectName": "gradle-language-server", - "env": { - "VSCODE_GRADLE_PORT": "6006" - }, - "presentation": { - "group": "debug", - "order": 5 - } - }, { "type": "java", "name": "Attach to Gradle Plugin", diff --git a/extension/src/Extension.ts b/extension/src/Extension.ts index 69c483b84..a35692d55 100644 --- a/extension/src/Extension.ts +++ b/extension/src/Extension.ts @@ -39,6 +39,7 @@ import { GradleBuildContentProvider } from "./client/GradleBuildContentProvider" import { BuildServerController } from "./bs/BuildServerController"; import { GradleTestRunner } from "./bs/GradleTestRunner"; import { BspProxy } from "./bs/BspProxy"; +import { generateRandomPipeName } from "./util/generateRandomPipeName"; export class Extension { private readonly bspProxy: BspProxy; @@ -71,7 +72,7 @@ export class Extension { private readonly onDidTerminalOpen: vscode.Event = this._onDidTerminalOpen.event; private recentTerminal: vscode.Terminal | undefined; private readonly buildServerController: BuildServerController; - + private readonly languageServerPipePath: string; public constructor(private readonly context: vscode.ExtensionContext) { const loggingChannel = vscode.window.createOutputChannel("Gradle for Java"); logger.setLoggingChannel(loggingChannel); @@ -85,13 +86,14 @@ export class Extension { const bspLogger = new Logger("bspProxy"); bspLogger.setLoggingChannel(loggingChannel); + this.languageServerPipePath = generateRandomPipeName(); if (getConfigIsDebugEnabled()) { Logger.setLogVerbosity(LogVerbosity.DEBUG); } const statusBarItem = vscode.window.createStatusBarItem(); this.bspProxy = new BspProxy(this.context, bspLogger); - this.server = new GradleServer({ host: "localhost" }, context, serverLogger, this.bspProxy); + this.server = new GradleServer({ host: "localhost" }, context, serverLogger, this.bspProxy, this.languageServerPipePath); this.client = new GradleClient(this.server, statusBarItem, clientLogger); this.pinnedTasksStore = new PinnedTasksStore(context); this.recentTasksStore = new RecentTasksStore(); @@ -206,8 +208,8 @@ export class Extension { ); this.client.onDidConnect(() => this.refresh()); + void startLanguageServer(this.context, this.gradleBuildContentProvider, this.rootProjectsStore, this.languageServerPipePath); void this.activate(); - void startLanguageServer(this.context, this.gradleBuildContentProvider, this.rootProjectsStore); void vscode.commands.executeCommand("setContext", "allowParallelRun", getAllowParallelRun()); void vscode.commands.executeCommand("setContext", Context.ACTIVATION_CONTEXT_KEY, true); } diff --git a/extension/src/languageServer/languageServer.ts b/extension/src/languageServer/languageServer.ts index d40d2cbd7..777c76c05 100644 --- a/extension/src/languageServer/languageServer.ts +++ b/extension/src/languageServer/languageServer.ts @@ -2,7 +2,6 @@ // Licensed under the MIT license. import * as net from "net"; -import * as path from "path"; import * as vscode from "vscode"; import { DidChangeConfigurationNotification, LanguageClientOptions } from "vscode-languageclient"; import { LanguageClient, StreamInfo } from "vscode-languageclient/node"; @@ -10,15 +9,11 @@ import { GradleBuildContentProvider } from "../client/GradleBuildContentProvider import { GradleBuild, GradleProject } from "../proto/gradle_pb"; import { RootProjectsStore } from "../stores"; import { - checkEnvJavaExecutable, getConfigJavaImportGradleHome, getConfigJavaImportGradleUserHome, getConfigJavaImportGradleVersion, - getConfigJavaImportGradleWrapperEnabled, - findValidJavaHome, - getJavaExecutablePathFromJavaHome, + getConfigJavaImportGradleWrapperEnabled } from "../util/config"; -import { prepareLanguageServerParams } from "./utils"; const CHANNEL_NAME = "Gradle for Java (Language Server)"; export let isLanguageServerStarted = false; @@ -26,11 +21,12 @@ export let isLanguageServerStarted = false; export async function startLanguageServer( context: vscode.ExtensionContext, contentProvider: GradleBuildContentProvider, - rootProjectsStore: RootProjectsStore + rootProjectsStore: RootProjectsStore, + languageServerPipePath: string ): Promise { void vscode.window.withProgress({ location: vscode.ProgressLocation.Window }, (progress) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars - return new Promise(async (resolve, reject) => { + return new Promise(async (resolve) => { progress.report({ message: "Initializing Gradle Language Server", }); @@ -42,40 +38,7 @@ export async function startLanguageServer( settings: getGradleSettings(), }, }; - let serverOptions; - if (process.env.VSCODE_DEBUG_LANGUAGE_SERVER === "true") { - // debug mode - const port = process.env.VSCODE_GRADLE_PORT; - if (!port) { - void vscode.window.showErrorMessage( - "VSCODE_GRADLE_PORT is invalid, please check it in launch.json." - ); - return; - } - serverOptions = awaitServerConnection.bind(null, port); - } else { - // keep consistent with gRPC server - const javaHome = await findValidJavaHome(); - let javaCommand; - if (javaHome) { - javaCommand = getJavaExecutablePathFromJavaHome(javaHome); - } else { - if (!checkEnvJavaExecutable()) { - // we have already show error message in gRPC server for no java executable found, so here we will just reject and return - return reject(); - } - javaCommand = "java"; - } - const args = [ - ...prepareLanguageServerParams(), - "-jar", - path.resolve(context.extensionPath, "lib", "gradle-language-server.jar"), - ]; - serverOptions = { - command: javaCommand, - args: args, - }; - } + let serverOptions = () => awaitServerConnection(languageServerPipePath) const languageClient = new LanguageClient("gradle", "Gradle Language Server", serverOptions, clientOptions); void languageClient.onReady().then( () => { @@ -88,6 +51,7 @@ export async function startLanguageServer( } ); const disposable = languageClient.start(); + context.subscriptions.push(disposable); context.subscriptions.push( vscode.workspace.onDidChangeConfiguration((e) => { @@ -102,15 +66,14 @@ export async function startLanguageServer( }); } -async function awaitServerConnection(port: string): Promise { - const addr = parseInt(port); +async function awaitServerConnection(pipeName: string): Promise { return new Promise((resolve, reject) => { const server = net.createServer((stream) => { server.close(); resolve({ reader: stream, writer: stream }); }); server.on("error", reject); - server.listen(addr, () => { + server.listen(pipeName, () => { server.removeListener("error", reject); }); return server; diff --git a/extension/src/server/GradleServer.ts b/extension/src/server/GradleServer.ts index 2b36d2054..947e88454 100644 --- a/extension/src/server/GradleServer.ts +++ b/extension/src/server/GradleServer.ts @@ -24,7 +24,6 @@ export class GradleServer { private ready = false; private taskServerPort: number | undefined; private restarting = false; - public readonly onDidStart: vscode.Event = this._onDidStart.event; public readonly onDidStop: vscode.Event = this._onDidStop.event; private process?: cp.ChildProcessWithoutNullStreams; @@ -33,7 +32,8 @@ export class GradleServer { private readonly opts: ServerOptions, private readonly context: vscode.ExtensionContext, private readonly logger: Logger, - private bspProxy: BspProxy + private bspProxy: BspProxy, + private languageServerPipePath: string ) {} public async start(): Promise { @@ -47,7 +47,7 @@ export class GradleServer { return; } const startBuildServer = redHatJavaInstalled() ? "true" : "false"; - const args = [`--port=${this.taskServerPort}`, `--startBuildServer=${startBuildServer}`]; + const args = [`--port=${this.taskServerPort}`, `--startBuildServer=${startBuildServer}`, `--languageServerPipePath=${this.languageServerPipePath}`]; if (startBuildServer === "true") { const buildServerPipeName = this.bspProxy.getBuildServerPipeName(); args.push(`--pipeName=${buildServerPipeName}`, `--bundleDir=${bundleDirectory}`); diff --git a/gradle-language-server/build.gradle b/gradle-language-server/build.gradle index 68ac210da..e23848d50 100644 --- a/gradle-language-server/build.gradle +++ b/gradle-language-server/build.gradle @@ -4,8 +4,8 @@ plugins { } java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } repositories { @@ -32,10 +32,16 @@ dependencies { ext.mainClass = "com.microsoft.gradle.GradleLanguageServer" -task copyJar(type: Copy) { - from "build/libs/gradle-language-server.jar" - from configurations.runtimeClasspath - into "../extension/lib" +task copyJar { + doLast { + ['../extension/lib', '../gradle-server/build/libs'].each { destDir -> + copy { + from "build/libs/gradle-language-server.jar" + from configurations.runtimeClasspath + into destDir + } + } + } } tasks.build.dependsOn tasks.copyJar diff --git a/gradle-language-server/src/main/java/com/microsoft/gradle/GradleLanguageServer.java b/gradle-language-server/src/main/java/com/microsoft/gradle/GradleLanguageServer.java index 47a92ca30..0dd5b8e25 100644 --- a/gradle-language-server/src/main/java/com/microsoft/gradle/GradleLanguageServer.java +++ b/gradle-language-server/src/main/java/com/microsoft/gradle/GradleLanguageServer.java @@ -7,8 +7,8 @@ import com.google.gson.JsonElement; import com.microsoft.gradle.semantictokens.TokenModifier; import com.microsoft.gradle.semantictokens.TokenType; +import com.microsoft.gradle.utils.NamedPipeStream; import java.io.IOException; -import java.net.Socket; import java.net.URI; import java.nio.file.Paths; import java.util.Arrays; @@ -35,7 +35,6 @@ import org.eclipse.lsp4j.services.LanguageServer; import org.eclipse.lsp4j.services.TextDocumentService; import org.eclipse.lsp4j.services.WorkspaceService; - public class GradleLanguageServer implements LanguageServer, LanguageClientAware { private GradleServices gradleServices; @@ -44,16 +43,10 @@ public static void main(String[] args) { GradleLanguageServer server = new GradleLanguageServer(); try { Launcher launcher; - String port = System.getenv("VSCODE_GRADLE_PORT"); - if (port == null) { - // Launch Mode - launcher = Launcher.createLauncher(server, LanguageClient.class, System.in, System.out); - } else { - // Debug Mode - Socket socket = new Socket("localhost", Integer.parseInt(port)); - launcher = Launcher.createLauncher(server, LanguageClient.class, socket.getInputStream(), - socket.getOutputStream()); - } + // Get named pipe path + NamedPipeStream pipeStream = new NamedPipeStream(args[0]); + launcher = Launcher.createLauncher(server, LanguageClient.class, pipeStream.getInputStream(), + pipeStream.getOutputStream()); server.connect(launcher.getRemoteProxy()); launcher.startListening(); } catch (IOException e) { diff --git a/gradle-language-server/src/main/java/com/microsoft/gradle/utils/NamedPipeStream.java b/gradle-language-server/src/main/java/com/microsoft/gradle/utils/NamedPipeStream.java new file mode 100644 index 000000000..e0a57c68b --- /dev/null +++ b/gradle-language-server/src/main/java/com/microsoft/gradle/utils/NamedPipeStream.java @@ -0,0 +1,210 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +package com.microsoft.gradle.utils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.StandardProtocolFamily; +import java.net.UnixDomainSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.AsynchronousFileChannel; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.SocketChannel; +import java.nio.channels.WritableByteChannel; +import java.nio.file.StandardOpenOption; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +/** + * A named pipe stream implementation. + */ +public class NamedPipeStream { + private String pipeName; + private StreamProvider provider; + + public NamedPipeStream(String pipeName) { + this.pipeName = pipeName; + } + + interface StreamProvider { + InputStream getInputStream() throws IOException; + + OutputStream getOutputStream() throws IOException; + } + + /** + * getSelectedStream. + */ + public StreamProvider getSelectedStream() { + if (provider == null) { + provider = createProvider(); + } + return provider; + } + + private StreamProvider createProvider() { + PipeStreamProvider pipeStreamProvider = new PipeStreamProvider(); + pipeStreamProvider.initializeNamedPipe(); + return pipeStreamProvider; + } + + public InputStream getInputStream() throws IOException { + return getSelectedStream().getInputStream(); + } + + public OutputStream getOutputStream() throws IOException { + return getSelectedStream().getOutputStream(); + } + + private static boolean isWindows() { + return System.getProperty("os.name").toLowerCase().contains("win"); + } + + /** + * PipeStreamProvider. + */ + protected final class PipeStreamProvider implements StreamProvider { + + private InputStream input; + private OutputStream output; + private String pipeName = NamedPipeStream.this.pipeName; + + @Override + public InputStream getInputStream() throws IOException { + return input; + } + + @Override + public OutputStream getOutputStream() throws IOException { + return output; + } + + private void initializeNamedPipe() { + File pipeFile = new File(this.pipeName); + try { + attemptConnection(pipeFile); + } catch (IOException e) { + throw new IllegalStateException("Error initializing the named pipe", e); + } + } + + private void attemptConnection(File pipeFile) throws IOException { + if (isWindows()) { + AsynchronousFileChannel channel = AsynchronousFileChannel.open(pipeFile.toPath(), + StandardOpenOption.READ, StandardOpenOption.WRITE); + input = new NamedPipeInputStream(channel); + output = new NamedPipeOutputStream(channel); + } else { + UnixDomainSocketAddress socketAddress = UnixDomainSocketAddress.of(pipeFile.toPath()); + SocketChannel channel = SocketChannel.open(StandardProtocolFamily.UNIX); + channel.connect(socketAddress); + input = new NamedPipeInputStream(channel); + output = new NamedPipeOutputStream(channel); + } + } + } + + /** + * NamedPipeInputStream. + */ + public class NamedPipeInputStream extends InputStream { + + private ReadableByteChannel unixChannel; + private AsynchronousFileChannel winChannel; + private ByteBuffer buffer = ByteBuffer.allocate(1024); + private int readyBytes = 0; + + public NamedPipeInputStream(ReadableByteChannel channel) { + this.unixChannel = channel; + } + + public NamedPipeInputStream(AsynchronousFileChannel channel) { + this.winChannel = channel; + } + + @Override + public int read() throws IOException { + if (buffer.position() < readyBytes) { + return buffer.get() & 0xFF; + } + try { + buffer.clear(); + if (winChannel != null) { + readyBytes = winChannel.read(buffer, 0).get(); + } else { + readyBytes = unixChannel.read(buffer); + } + if (readyBytes == -1) { + return -1; // EOF + } + buffer.flip(); + return buffer.get() & 0xFF; + } catch (InterruptedException | ExecutionException e) { + throw new IOException(e); + } + } + } + + /** + * NamedPipeOutputStream. + */ + public class NamedPipeOutputStream extends OutputStream { + private WritableByteChannel unixChannel; + private AsynchronousFileChannel winChannel; + private ByteBuffer buffer = ByteBuffer.allocate(1); + + public NamedPipeOutputStream(WritableByteChannel channel) { + this.unixChannel = channel; + } + + public NamedPipeOutputStream(AsynchronousFileChannel channel) { + this.winChannel = channel; + } + + @Override + public void write(int b) throws IOException { + buffer.clear(); + buffer.put((byte) b); + buffer.position(0); + if (winChannel != null) { + Future result = winChannel.write(buffer, 0); + try { + result.get(); + } catch (Exception e) { + throw new IOException(e); + } + } else { + unixChannel.write(buffer); + } + } + + @Override + public void write(byte[] b) throws IOException { + final int buffer_size = 1024; + int blocks = b.length / buffer_size; + int writeBytes = 0; + for (int i = 0; i <= blocks; i++) { + int offset = i * buffer_size; + int length = Math.min(b.length - writeBytes, buffer_size); + if (length <= 0) { + break; + } + writeBytes += length; + ByteBuffer buffer = ByteBuffer.wrap(b, offset, length); + if (winChannel != null) { + Future result = winChannel.write(buffer, 0); + try { + result.get(); + } catch (Exception e) { + throw new IOException(e); + } + } else { + unixChannel.write(buffer); + } + } + } + } +} diff --git a/gradle-server/build.gradle b/gradle-server/build.gradle index 62720a014..b2d7806df 100644 --- a/gradle-server/build.gradle +++ b/gradle-server/build.gradle @@ -13,6 +13,11 @@ java { dependencies { implementation project(":gradle-plugin-api") implementation files('build/libs/server.jar') + implementation files('build/libs/gradle-language-server.jar') + implementation "org.eclipse.lsp4j:org.eclipse.lsp4j:0.12.0" + implementation "org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.12.0" + implementation "com.google.code.gson:gson:2.8.9" + implementation "org.apache.bcel:bcel:6.6.1" implementation fileTree(dir: 'build/libs/runtime', include: ['*.jar'], exclude: ['gradle-tooling-api-*.jar', 'slf4j-api-*.jar']) implementation("org.gradle:gradle-tooling-api:${toolingAPIVersion}") implementation 'javax.annotation:javax.annotation-api:1.3.2' @@ -127,6 +132,7 @@ task copyRuntimeLibs(type: Copy) { into "../extension/lib" from configurations.runtimeClasspath duplicatesStrategy = 'exclude' + duplicatesStrategy = 'exclude' } project.tasks.named("processResources") { diff --git a/gradle-server/src/main/java/com/github/badsyntax/gradle/GradleServer.java b/gradle-server/src/main/java/com/github/badsyntax/gradle/GradleServer.java index bdf611ecd..e94525402 100644 --- a/gradle-server/src/main/java/com/github/badsyntax/gradle/GradleServer.java +++ b/gradle-server/src/main/java/com/github/badsyntax/gradle/GradleServer.java @@ -1,6 +1,7 @@ package com.github.badsyntax.gradle; import com.github.badsyntax.gradle.utils.Utils; +import com.microsoft.gradle.GradleLanguageServer; import io.grpc.Server; import io.grpc.ServerBuilder; import java.io.IOException; @@ -65,7 +66,9 @@ public static void main(String[] args) throws Exception { if (startBuildServer) { String buildServerPipeName = Utils.validateRequiredParam(params, "pipeName"); String bundleDirectory = Utils.validateRequiredParam(params, "bundleDir"); + String languageServerPipePath = Utils.validateRequiredParam(params, "languageServerPipePath"); startBuildServerThread(buildServerPipeName, bundleDirectory); + startLanguageServerThread(languageServerPipePath); } } @@ -87,4 +90,15 @@ private static void startBuildServerThread(String pipeName, String directory) { Thread buildServerThread = new Thread(buildServerConnectionThread); buildServerThread.start(); } + + private static void startLanguageServerThread(String languageServerPipePath) { + Thread languageServerThread = new Thread(() -> { + try { + GradleLanguageServer.main(new String[]{languageServerPipePath}); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + languageServerThread.start(); + } } From 2c5d248768e9a1d5aea198f7c913dce5243c8320 Mon Sep 17 00:00:00 2001 From: Jiaaming <2455951489@qq.com> Date: Tue, 23 Jul 2024 10:49:13 +0800 Subject: [PATCH 2/6] Fix: comments --- extension/src/Extension.ts | 46 +++++++++++++------ .../src/languageServer/languageServer.ts | 6 +-- extension/src/server/GradleServer.ts | 6 ++- .../gradle/GradleLanguageServer.java | 6 +-- .../{utils => transport}/NamedPipeStream.java | 2 +- gradle-server/build.gradle | 1 - .../github/badsyntax/gradle/GradleServer.java | 6 +-- 7 files changed, 44 insertions(+), 29 deletions(-) rename gradle-language-server/src/main/java/com/microsoft/gradle/{utils => transport}/NamedPipeStream.java (99%) diff --git a/extension/src/Extension.ts b/extension/src/Extension.ts index a35692d55..4c96d673c 100644 --- a/extension/src/Extension.ts +++ b/extension/src/Extension.ts @@ -22,7 +22,7 @@ import { FileWatcher } from "./util/FileWatcher"; import { DependencyTreeItem } from "./views/gradleTasks/DependencyTreeItem"; import { GRADLE_DEPENDENCY_REVEAL } from "./views/gradleTasks/DependencyUtils"; import { GradleDependencyProvider } from "./dependencies/GradleDependencyProvider"; -import { isLanguageServerStarted, startLanguageServer } from "./languageServer/languageServer"; +import { isLanguageServerStarted, startLanguageClientAndWaitForConnection } from "./languageServer/languageServer"; import { DefaultProjectsTreeDataProvider } from "./views/defaultProject/DefaultProjectsTreeDataProvider"; import { CompletionKinds, @@ -43,7 +43,7 @@ import { generateRandomPipeName } from "./util/generateRandomPipeName"; export class Extension { private readonly bspProxy: BspProxy; - private readonly client: GradleClient; + private readonly taskServerClient: GradleClient; private readonly server: GradleServer; private readonly pinnedTasksStore: PinnedTasksStore; private readonly recentTasksStore: RecentTasksStore; @@ -93,16 +93,22 @@ export class Extension { const statusBarItem = vscode.window.createStatusBarItem(); this.bspProxy = new BspProxy(this.context, bspLogger); - this.server = new GradleServer({ host: "localhost" }, context, serverLogger, this.bspProxy, this.languageServerPipePath); - this.client = new GradleClient(this.server, statusBarItem, clientLogger); + this.server = new GradleServer( + { host: "localhost" }, + context, + serverLogger, + this.bspProxy, + this.languageServerPipePath + ); + this.taskServerClient = new GradleClient(this.server, statusBarItem, clientLogger); this.pinnedTasksStore = new PinnedTasksStore(context); this.recentTasksStore = new RecentTasksStore(); this.taskTerminalsStore = new TaskTerminalsStore(); this.rootProjectsStore = new RootProjectsStore(); - this.gradleBuildContentProvider = new GradleBuildContentProvider(this.client); + this.gradleBuildContentProvider = new GradleBuildContentProvider(this.taskServerClient); this.gradleTaskProvider = new GradleTaskProvider( this.rootProjectsStore, - this.client, + this.taskServerClient, this.gradleBuildContentProvider ); this.gradleDependencyProvider = new GradleDependencyProvider(this.gradleBuildContentProvider); @@ -116,7 +122,7 @@ export class Extension { this.gradleTaskProvider, this.gradleDependencyProvider, this.icons, - this.client + this.taskServerClient ); this.gradleTasksTreeView = vscode.window.createTreeView(GRADLE_TASKS_VIEW, { treeDataProvider: this.gradleTasksTreeDataProvider, @@ -132,7 +138,7 @@ export class Extension { this.taskTerminalsStore, this.rootProjectsStore, this.gradleTaskProvider, - this.client, + this.taskServerClient, this.icons ); this.recentTasksTreeView = vscode.window.createTreeView(RECENT_TASKS_VIEW, { @@ -142,7 +148,7 @@ export class Extension { this.defaultProjectsTreeDataProvider = new DefaultProjectsTreeDataProvider( this.gradleTaskProvider, this.rootProjectsStore, - this.client, + this.taskServerClient, this.icons ); this.defaultProjectsTreeView = vscode.window.createTreeView(GRADLE_DEFAULT_PROJECTS_VIEW, { @@ -153,7 +159,12 @@ export class Extension { this.gradleTaskManager = new GradleTaskManager(context); this.buildFileWatcher = new FileWatcher("**/*.{gradle,gradle.kts}"); this.gradleWrapperWatcher = new FileWatcher("**/gradle/wrapper/gradle-wrapper.properties"); - this.api = new Api(this.client, this.gradleTasksTreeDataProvider, this.gradleTaskProvider, this.icons); + this.api = new Api( + this.taskServerClient, + this.gradleTasksTreeDataProvider, + this.gradleTaskProvider, + this.icons + ); this.commands = new Commands( this.context, @@ -163,7 +174,7 @@ export class Extension { this.gradleTasksTreeDataProvider, this.recentTasksTreeDataProvider, this.gradleDaemonsTreeDataProvider, - this.client, + this.taskServerClient, this.rootProjectsStore, this.taskTerminalsStore, this.recentTasksStore, @@ -207,8 +218,13 @@ export class Extension { ) ); - this.client.onDidConnect(() => this.refresh()); - void startLanguageServer(this.context, this.gradleBuildContentProvider, this.rootProjectsStore, this.languageServerPipePath); + this.taskServerClient.onDidConnect(() => this.refresh()); + void startLanguageClientAndWaitForConnection( + this.context, + this.gradleBuildContentProvider, + this.rootProjectsStore, + this.languageServerPipePath + ); void this.activate(); void vscode.commands.executeCommand("setContext", "allowParallelRun", getAllowParallelRun()); void vscode.commands.executeCommand("setContext", Context.ACTIVATION_CONTEXT_KEY, true); @@ -216,7 +232,7 @@ export class Extension { private storeSubscriptions(): void { this.context.subscriptions.push( - this.client, + this.taskServerClient, this.pinnedTasksStore, this.recentTasksStore, this.taskTerminalsStore, @@ -329,7 +345,7 @@ export class Extension { } private async restartServer(): Promise { - await this.client.cancelBuilds(); + await this.taskServerClient.cancelBuilds(); await commands.executeCommand("workbench.action.restartExtensionHost"); } diff --git a/extension/src/languageServer/languageServer.ts b/extension/src/languageServer/languageServer.ts index 777c76c05..04356ac72 100644 --- a/extension/src/languageServer/languageServer.ts +++ b/extension/src/languageServer/languageServer.ts @@ -12,13 +12,13 @@ import { getConfigJavaImportGradleHome, getConfigJavaImportGradleUserHome, getConfigJavaImportGradleVersion, - getConfigJavaImportGradleWrapperEnabled + getConfigJavaImportGradleWrapperEnabled, } from "../util/config"; const CHANNEL_NAME = "Gradle for Java (Language Server)"; export let isLanguageServerStarted = false; -export async function startLanguageServer( +export async function startLanguageClientAndWaitForConnection( context: vscode.ExtensionContext, contentProvider: GradleBuildContentProvider, rootProjectsStore: RootProjectsStore, @@ -38,7 +38,7 @@ export async function startLanguageServer( settings: getGradleSettings(), }, }; - let serverOptions = () => awaitServerConnection(languageServerPipePath) + const serverOptions = () => awaitServerConnection(languageServerPipePath); const languageClient = new LanguageClient("gradle", "Gradle Language Server", serverOptions, clientOptions); void languageClient.onReady().then( () => { diff --git a/extension/src/server/GradleServer.ts b/extension/src/server/GradleServer.ts index 947e88454..4cc4b753a 100644 --- a/extension/src/server/GradleServer.ts +++ b/extension/src/server/GradleServer.ts @@ -47,7 +47,11 @@ export class GradleServer { return; } const startBuildServer = redHatJavaInstalled() ? "true" : "false"; - const args = [`--port=${this.taskServerPort}`, `--startBuildServer=${startBuildServer}`, `--languageServerPipePath=${this.languageServerPipePath}`]; + const args = [ + `--port=${this.taskServerPort}`, + `--startBuildServer=${startBuildServer}`, + `--languageServerPipePath=${this.languageServerPipePath}`, + ]; if (startBuildServer === "true") { const buildServerPipeName = this.bspProxy.getBuildServerPipeName(); args.push(`--pipeName=${buildServerPipeName}`, `--bundleDir=${bundleDirectory}`); diff --git a/gradle-language-server/src/main/java/com/microsoft/gradle/GradleLanguageServer.java b/gradle-language-server/src/main/java/com/microsoft/gradle/GradleLanguageServer.java index 0dd5b8e25..c1e669935 100644 --- a/gradle-language-server/src/main/java/com/microsoft/gradle/GradleLanguageServer.java +++ b/gradle-language-server/src/main/java/com/microsoft/gradle/GradleLanguageServer.java @@ -7,7 +7,7 @@ import com.google.gson.JsonElement; import com.microsoft.gradle.semantictokens.TokenModifier; import com.microsoft.gradle.semantictokens.TokenType; -import com.microsoft.gradle.utils.NamedPipeStream; +import com.microsoft.gradle.transport.NamedPipeStream; import java.io.IOException; import java.net.URI; import java.nio.file.Paths; @@ -42,9 +42,9 @@ public class GradleLanguageServer implements LanguageServer, LanguageClientAware public static void main(String[] args) { GradleLanguageServer server = new GradleLanguageServer(); try { - Launcher launcher; - // Get named pipe path NamedPipeStream pipeStream = new NamedPipeStream(args[0]); + + Launcher launcher; launcher = Launcher.createLauncher(server, LanguageClient.class, pipeStream.getInputStream(), pipeStream.getOutputStream()); server.connect(launcher.getRemoteProxy()); diff --git a/gradle-language-server/src/main/java/com/microsoft/gradle/utils/NamedPipeStream.java b/gradle-language-server/src/main/java/com/microsoft/gradle/transport/NamedPipeStream.java similarity index 99% rename from gradle-language-server/src/main/java/com/microsoft/gradle/utils/NamedPipeStream.java rename to gradle-language-server/src/main/java/com/microsoft/gradle/transport/NamedPipeStream.java index e0a57c68b..1d045814a 100644 --- a/gradle-language-server/src/main/java/com/microsoft/gradle/utils/NamedPipeStream.java +++ b/gradle-language-server/src/main/java/com/microsoft/gradle/transport/NamedPipeStream.java @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. -package com.microsoft.gradle.utils; +package com.microsoft.gradle.transport; import java.io.File; import java.io.IOException; diff --git a/gradle-server/build.gradle b/gradle-server/build.gradle index b2d7806df..767a315d7 100644 --- a/gradle-server/build.gradle +++ b/gradle-server/build.gradle @@ -132,7 +132,6 @@ task copyRuntimeLibs(type: Copy) { into "../extension/lib" from configurations.runtimeClasspath duplicatesStrategy = 'exclude' - duplicatesStrategy = 'exclude' } project.tasks.named("processResources") { diff --git a/gradle-server/src/main/java/com/github/badsyntax/gradle/GradleServer.java b/gradle-server/src/main/java/com/github/badsyntax/gradle/GradleServer.java index e94525402..231a9dc23 100644 --- a/gradle-server/src/main/java/com/github/badsyntax/gradle/GradleServer.java +++ b/gradle-server/src/main/java/com/github/badsyntax/gradle/GradleServer.java @@ -93,11 +93,7 @@ private static void startBuildServerThread(String pipeName, String directory) { private static void startLanguageServerThread(String languageServerPipePath) { Thread languageServerThread = new Thread(() -> { - try { - GradleLanguageServer.main(new String[]{languageServerPipePath}); - } catch (Exception e) { - throw new RuntimeException(e); - } + GradleLanguageServer.main(new String[]{languageServerPipePath}); }); languageServerThread.start(); } From b7ba9bce9d4c0741079bf1f584bf7b05180361a0 Mon Sep 17 00:00:00 2001 From: Jiaaming <2455951489@qq.com> Date: Tue, 23 Jul 2024 13:26:20 +0800 Subject: [PATCH 3/6] Fix:dependency logic --- gradle-language-server/build.gradle | 20 +++++++------------- gradle-server/build.gradle | 11 ++++------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/gradle-language-server/build.gradle b/gradle-language-server/build.gradle index e23848d50..81f0e2bd5 100644 --- a/gradle-language-server/build.gradle +++ b/gradle-language-server/build.gradle @@ -21,10 +21,10 @@ application { } dependencies { - implementation "org.eclipse.lsp4j:org.eclipse.lsp4j:0.12.0" - implementation "org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.12.0" + implementation "org.eclipse.lsp4j:org.eclipse.lsp4j:0.19.0" + implementation "org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.19.0" implementation "org.codehaus.groovy:groovy-eclipse-batch:4.0.16-03" - implementation "com.google.code.gson:gson:2.8.9" + implementation "com.google.code.gson:gson:2.9.1" implementation "org.apache.bcel:bcel:6.6.1" testImplementation "org.junit.jupiter:junit-jupiter-api:5.8.1" testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.8.1" @@ -32,16 +32,10 @@ dependencies { ext.mainClass = "com.microsoft.gradle.GradleLanguageServer" -task copyJar { - doLast { - ['../extension/lib', '../gradle-server/build/libs'].each { destDir -> - copy { - from "build/libs/gradle-language-server.jar" - from configurations.runtimeClasspath - into destDir - } - } - } +task copyJar(type: Copy) { + from "build/libs/gradle-language-server.jar" + from configurations.runtimeClasspath + into "../gradle-server/build/libs" } tasks.build.dependsOn tasks.copyJar diff --git a/gradle-server/build.gradle b/gradle-server/build.gradle index 767a315d7..53ae7b293 100644 --- a/gradle-server/build.gradle +++ b/gradle-server/build.gradle @@ -12,13 +12,9 @@ java { dependencies { implementation project(":gradle-plugin-api") - implementation files('build/libs/server.jar') + implementation fileTree(dir: 'build/libs', include: ['*.jar']) implementation files('build/libs/gradle-language-server.jar') - implementation "org.eclipse.lsp4j:org.eclipse.lsp4j:0.12.0" - implementation "org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.12.0" - implementation "com.google.code.gson:gson:2.8.9" - implementation "org.apache.bcel:bcel:6.6.1" - implementation fileTree(dir: 'build/libs/runtime', include: ['*.jar'], exclude: ['gradle-tooling-api-*.jar', 'slf4j-api-*.jar']) + implementation fileTree(dir: 'build/libs/runtime', include: ['*.jar'], exclude: ['gradle-tooling-api-*.jar', 'slf4j-api-*.jar', 'gson-*.jar', 'org.eclipse.lsp4j*.jar'])// implementation("org.gradle:gradle-tooling-api:${toolingAPIVersion}") implementation 'javax.annotation:javax.annotation-api:1.3.2' implementation "io.grpc:grpc-protobuf:${grpcVersion}" @@ -132,6 +128,7 @@ task copyRuntimeLibs(type: Copy) { into "../extension/lib" from configurations.runtimeClasspath duplicatesStrategy = 'exclude' + mustRunAfter ':gradle-language-server:copyJar' } project.tasks.named("processResources") { @@ -149,5 +146,5 @@ test { } -compileJava.dependsOn 'generateProto', 'spotlessCheck' +compileJava.dependsOn 'generateProto', 'spotlessCheck', ':gradle-language-server:copyJar' assemble.dependsOn serverStartScripts From 12e1c523cce49b04f385589ccf56aa6354323200 Mon Sep 17 00:00:00 2001 From: Jiaaming <2455951489@qq.com> Date: Tue, 23 Jul 2024 13:37:38 +0800 Subject: [PATCH 4/6] Remove language server channel; Fix typo --- extension/src/languageServer/languageServer.ts | 3 --- gradle-server/build.gradle | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/extension/src/languageServer/languageServer.ts b/extension/src/languageServer/languageServer.ts index 04356ac72..35d88d14f 100644 --- a/extension/src/languageServer/languageServer.ts +++ b/extension/src/languageServer/languageServer.ts @@ -14,7 +14,6 @@ import { getConfigJavaImportGradleVersion, getConfigJavaImportGradleWrapperEnabled, } from "../util/config"; -const CHANNEL_NAME = "Gradle for Java (Language Server)"; export let isLanguageServerStarted = false; @@ -32,8 +31,6 @@ export async function startLanguageClientAndWaitForConnection( }); const clientOptions: LanguageClientOptions = { documentSelector: [{ scheme: "file", language: "gradle" }], - outputChannel: vscode.window.createOutputChannel(CHANNEL_NAME), - outputChannelName: CHANNEL_NAME, initializationOptions: { settings: getGradleSettings(), }, diff --git a/gradle-server/build.gradle b/gradle-server/build.gradle index 53ae7b293..a8b0437fd 100644 --- a/gradle-server/build.gradle +++ b/gradle-server/build.gradle @@ -14,7 +14,7 @@ dependencies { implementation project(":gradle-plugin-api") implementation fileTree(dir: 'build/libs', include: ['*.jar']) implementation files('build/libs/gradle-language-server.jar') - implementation fileTree(dir: 'build/libs/runtime', include: ['*.jar'], exclude: ['gradle-tooling-api-*.jar', 'slf4j-api-*.jar', 'gson-*.jar', 'org.eclipse.lsp4j*.jar'])// + implementation fileTree(dir: 'build/libs/runtime', include: ['*.jar'], exclude: ['gradle-tooling-api-*.jar', 'slf4j-api-*.jar', 'gson-*.jar', 'org.eclipse.lsp4j*.jar']) implementation("org.gradle:gradle-tooling-api:${toolingAPIVersion}") implementation 'javax.annotation:javax.annotation-api:1.3.2' implementation "io.grpc:grpc-protobuf:${grpcVersion}" From 674588749993209d84415ecc48ffc79ff1fae210 Mon Sep 17 00:00:00 2001 From: Jiaaming <2455951489@qq.com> Date: Wed, 24 Jul 2024 12:45:38 +0800 Subject: [PATCH 5/6] Fix: comments --- extension/src/Extension.ts | 13 ++------- extension/src/server/GradleServer.ts | 25 ++++++++++++++--- gradle-language-server/build.gradle | 28 ++++++++----------- .../gradle/GradleLanguageServer.java | 4 +++ gradle-server/build.gradle | 13 ++++----- 5 files changed, 45 insertions(+), 38 deletions(-) diff --git a/extension/src/Extension.ts b/extension/src/Extension.ts index 4c96d673c..540921d3d 100644 --- a/extension/src/Extension.ts +++ b/extension/src/Extension.ts @@ -39,7 +39,6 @@ import { GradleBuildContentProvider } from "./client/GradleBuildContentProvider" import { BuildServerController } from "./bs/BuildServerController"; import { GradleTestRunner } from "./bs/GradleTestRunner"; import { BspProxy } from "./bs/BspProxy"; -import { generateRandomPipeName } from "./util/generateRandomPipeName"; export class Extension { private readonly bspProxy: BspProxy; @@ -72,7 +71,6 @@ export class Extension { private readonly onDidTerminalOpen: vscode.Event = this._onDidTerminalOpen.event; private recentTerminal: vscode.Terminal | undefined; private readonly buildServerController: BuildServerController; - private readonly languageServerPipePath: string; public constructor(private readonly context: vscode.ExtensionContext) { const loggingChannel = vscode.window.createOutputChannel("Gradle for Java"); logger.setLoggingChannel(loggingChannel); @@ -86,20 +84,13 @@ export class Extension { const bspLogger = new Logger("bspProxy"); bspLogger.setLoggingChannel(loggingChannel); - this.languageServerPipePath = generateRandomPipeName(); if (getConfigIsDebugEnabled()) { Logger.setLogVerbosity(LogVerbosity.DEBUG); } const statusBarItem = vscode.window.createStatusBarItem(); this.bspProxy = new BspProxy(this.context, bspLogger); - this.server = new GradleServer( - { host: "localhost" }, - context, - serverLogger, - this.bspProxy, - this.languageServerPipePath - ); + this.server = new GradleServer({ host: "localhost" }, context, serverLogger, this.bspProxy); this.taskServerClient = new GradleClient(this.server, statusBarItem, clientLogger); this.pinnedTasksStore = new PinnedTasksStore(context); this.recentTasksStore = new RecentTasksStore(); @@ -223,7 +214,7 @@ export class Extension { this.context, this.gradleBuildContentProvider, this.rootProjectsStore, - this.languageServerPipePath + this.server.getLanguageServerPipePath() ); void this.activate(); void vscode.commands.executeCommand("setContext", "allowParallelRun", getAllowParallelRun()); diff --git a/extension/src/server/GradleServer.ts b/extension/src/server/GradleServer.ts index 4cc4b753a..f0a346a31 100644 --- a/extension/src/server/GradleServer.ts +++ b/extension/src/server/GradleServer.ts @@ -10,7 +10,7 @@ import { Logger } from "../logger/index"; import { NO_JAVA_EXECUTABLE, OPT_RESTART } from "../constant"; import { redHatJavaInstalled } from "../util/config"; import { BspProxy } from "../bs/BspProxy"; - +import { generateRandomPipeName } from "../util/generateRandomPipeName"; const SERVER_LOGLEVEL_REGEX = /^\[([A-Z]+)\](.*)$/; const DOWNLOAD_PROGRESS_CHAR = "."; @@ -27,15 +27,32 @@ export class GradleServer { public readonly onDidStart: vscode.Event = this._onDidStart.event; public readonly onDidStop: vscode.Event = this._onDidStop.event; private process?: cp.ChildProcessWithoutNullStreams; + private languageServerPipePath: string; constructor( private readonly opts: ServerOptions, private readonly context: vscode.ExtensionContext, private readonly logger: Logger, - private bspProxy: BspProxy, - private languageServerPipePath: string - ) {} + private bspProxy: BspProxy + ) { + this.setLanguageServerPipePath(); + } + public setLanguageServerPipePath(): void { + try { + this.languageServerPipePath = generateRandomPipeName(); + } catch (error) { + this.languageServerPipePath = ""; + this.logger.error("Failed to generate language server pipe path", error.message); + sendInfo("", { + kind: "languageServerPipePathGenerationError", + }); + } + } + + public getLanguageServerPipePath(): string { + return this.languageServerPipePath; + } public async start(): Promise { this.taskServerPort = await getPort(); const cwd = this.context.asAbsolutePath("lib"); diff --git a/gradle-language-server/build.gradle b/gradle-language-server/build.gradle index 81f0e2bd5..0358c3471 100644 --- a/gradle-language-server/build.gradle +++ b/gradle-language-server/build.gradle @@ -32,22 +32,18 @@ dependencies { ext.mainClass = "com.microsoft.gradle.GradleLanguageServer" -task copyJar(type: Copy) { - from "build/libs/gradle-language-server.jar" - from configurations.runtimeClasspath - into "../gradle-server/build/libs" -} - -tasks.build.dependsOn tasks.copyJar -tasks.copyJar.dependsOn jar - -jar { - manifest { - attributes( - "Main-Class": "com.microsoft.gradle.GradleLanguageServer", - "Class-Path": configurations.runtimeClasspath.collect { it.getName() }.join(' ') - ) - } +task customFatJar(type: Jar) { + manifest { + attributes( + "Main-Class": "com.microsoft.gradle.GradleLanguageServer", + ) + } + archiveBaseName = 'ls-fat-jar' + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } + exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA' + destinationDirectory = file('../gradle-server/build/libs') + with jar } def mainJavaDir = 'src/main/java'; diff --git a/gradle-language-server/src/main/java/com/microsoft/gradle/GradleLanguageServer.java b/gradle-language-server/src/main/java/com/microsoft/gradle/GradleLanguageServer.java index c1e669935..1a7e8a460 100644 --- a/gradle-language-server/src/main/java/com/microsoft/gradle/GradleLanguageServer.java +++ b/gradle-language-server/src/main/java/com/microsoft/gradle/GradleLanguageServer.java @@ -16,6 +16,7 @@ import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; import org.eclipse.lsp4j.CompletionOptions; import org.eclipse.lsp4j.DocumentFilter; import org.eclipse.lsp4j.ExecuteCommandOptions; @@ -41,6 +42,9 @@ public class GradleLanguageServer implements LanguageServer, LanguageClientAware public static void main(String[] args) { GradleLanguageServer server = new GradleLanguageServer(); + if (StringUtils.isBlank(args[0])) { + server.exit(); + } try { NamedPipeStream pipeStream = new NamedPipeStream(args[0]); diff --git a/gradle-server/build.gradle b/gradle-server/build.gradle index a8b0437fd..bba2d9957 100644 --- a/gradle-server/build.gradle +++ b/gradle-server/build.gradle @@ -12,14 +12,15 @@ java { dependencies { implementation project(":gradle-plugin-api") - implementation fileTree(dir: 'build/libs', include: ['*.jar']) - implementation files('build/libs/gradle-language-server.jar') - implementation fileTree(dir: 'build/libs/runtime', include: ['*.jar'], exclude: ['gradle-tooling-api-*.jar', 'slf4j-api-*.jar', 'gson-*.jar', 'org.eclipse.lsp4j*.jar']) + implementation files('build/libs/server.jar') + implementation fileTree(dir: 'build/libs/runtime', include: ['*.jar'], exclude: ['gradle-tooling-api-*.jar', + 'slf4j-api-*.jar']) implementation("org.gradle:gradle-tooling-api:${toolingAPIVersion}") implementation 'javax.annotation:javax.annotation-api:1.3.2' implementation "io.grpc:grpc-protobuf:${grpcVersion}" implementation "io.grpc:grpc-stub:${grpcVersion}" implementation 'io.github.g00fy2:versioncompare:1.4.1' + implementation files('build/libs/ls-fat-jar.jar') runtimeOnly "io.grpc:grpc-netty:${grpcVersion}" runtimeOnly 'org.slf4j:slf4j-simple:2.0.0-alpha6' testImplementation "io.grpc:grpc-testing:${grpcVersion}" @@ -110,7 +111,6 @@ spotless { task serverStartScripts(type: CreateStartScripts) { dependsOn jar dependsOn 'copyRuntimeLibs' - dependsOn(':gradle-language-server:copyJar') outputDir = file(libsDir) mainClass = 'com.github.badsyntax.gradle.GradleServer' applicationName = project.name @@ -128,7 +128,7 @@ task copyRuntimeLibs(type: Copy) { into "../extension/lib" from configurations.runtimeClasspath duplicatesStrategy = 'exclude' - mustRunAfter ':gradle-language-server:copyJar' + mustRunAfter ':gradle-language-server:customFatJar' } project.tasks.named("processResources") { @@ -145,6 +145,5 @@ test { '--add-opens=java.base/sun.nio.fs=ALL-UNNAMED' } - -compileJava.dependsOn 'generateProto', 'spotlessCheck', ':gradle-language-server:copyJar' +compileJava.dependsOn 'generateProto', 'spotlessCheck', ':gradle-language-server:customFatJar' assemble.dependsOn serverStartScripts From cfdbedacb6d2901a40982a3014445ea58149aedb Mon Sep 17 00:00:00 2001 From: Jiaaming <2455951489@qq.com> Date: Wed, 24 Jul 2024 13:32:55 +0800 Subject: [PATCH 6/6] Fix: vis --- extension/src/server/GradleServer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extension/src/server/GradleServer.ts b/extension/src/server/GradleServer.ts index f0a346a31..b96ebd9cc 100644 --- a/extension/src/server/GradleServer.ts +++ b/extension/src/server/GradleServer.ts @@ -38,7 +38,7 @@ export class GradleServer { this.setLanguageServerPipePath(); } - public setLanguageServerPipePath(): void { + private setLanguageServerPipePath(): void { try { this.languageServerPipePath = generateRandomPipeName(); } catch (error) {