fwcd / kotlin-language-server

Kotlin code completion, diagnostics and more for any editor/IDE using the Language Server Protocol
MIT License
1.58k stars 202 forks source link

java.util.concurrent.TimeoutException: Unable to connect language server #565

Open abodinagdat16 opened 4 months ago

abodinagdat16 commented 4 months ago

I use this code to start the server in android:

package com.example.sionora;

import android.app.Service;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.IBinder;
import android.content.Intent;
import android.os.NetworkOnMainThreadException;
import android.widget.Toast;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.eclipse.lsp4j.jsonrpc.Launcher;
import org.javacs.kt.CompilerConfiguration;
import org.javacs.kt.Configuration;
import org.javacs.kt.JVMConfiguration;
import org.javacs.kt.KotlinLanguageServer;
import org.jetbrains.kotlin.idea.KotlinLanguage;

public class SinoraService extends Service {

  @Override
  public IBinder onBind(Intent arg0) {
      return null;
  }

    @Override
    public int onStartCommand(Intent arg0, int arg1, int arg2) {
        new Thread(() -> {
        try {
            ServerSocket serverSocket = new ServerSocket(8080);
            Socket socket = serverSocket.accept();
            KotlinLanguageServer kls = new KotlinLanguageServer();
            var outputStream = socket.getOutputStream();
            var inputStream = socket.getInputStream();
            var launcher = Launcher.createLauncher(kls, LanguageServerTestFixture.class, inputStream, outputStream);
            var remoteProxy = launcher.getRemoteProxy();
            kls.connect(remoteProxy);
            launcher.startListening().get(Long.MAX_VALUE, TimeUnit.SECONDS);
        } catch (NetworkOnMainThreadException | TimeoutException | InterruptedException | ExecutionException | IOException err) {
            copyText(getApplicationContext(), err.toString());
            Toast.makeText(getApplicationContext(), err.toString(), Toast.LENGTH_SHORT).show();
        }
    }).start();

        return START_STICKY;
    }
    public static void copyText(Context context, String text) {
    ClipboardManager cm = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
    ClipData cd = ClipData.newPlainText("noe", text);
    cm.setPrimaryClip(cd);
  }

}

and the client class:

package com.example.sionora;

import java.nio.file.Files;
import org.eclipse.lsp4j.*;
import org.eclipse.lsp4j.services.LanguageClient;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.javacs.kt.Configuration;
import org.javacs.kt.KotlinLanguageServer;

public abstract class LanguageServerTestFixture implements LanguageClient {
    protected final Path workspaceRoot;
    protected final KotlinLanguageServer languageServer;

    protected List<Diagnostic> diagnostics;

    public LanguageServerTestFixture(String relativeWorkspaceRoot, Configuration config) {
        this.workspaceRoot = absoluteWorkspaceRoot(relativeWorkspaceRoot);
        this.languageServer = createLanguageServer(config);
    }

    public Path absoluteWorkspaceRoot(String relativeWorkspaceRoot) {
        Path testResources = testResourcesRoot();
        return testResources.resolve(relativeWorkspaceRoot);
    }

    private KotlinLanguageServer createLanguageServer(Configuration config) {
        KotlinLanguageServer languageServer = new KotlinLanguageServer(config);
        InitializeParams init = new InitializeParams();
        init.setCapabilities(new ClientCapabilities());
        init.getCapabilities().setTextDocument(new TextDocumentClientCapabilities());
        init.getCapabilities().getTextDocument().setCompletion(new CompletionCapabilities());
        init.getCapabilities().getTextDocument().getCompletion().setCompletionItem(new CompletionItemCapabilities());
        init.getCapabilities().getTextDocument().getCompletion().getCompletionItem().setSnippetSupport(true);
        init.setWorkspaceFolders(List.of(new WorkspaceFolder()));
        init.getWorkspaceFolders().get(0).setName(workspaceRoot.getFileName().toString());
        init.getWorkspaceFolders().get(0).setUri(workspaceRoot.toUri().toString());
        languageServer.connect(this);
        languageServer.initialize(init).join();
        return languageServer;
    }

    public void closeLanguageServer() {
        languageServer.close();
    }

    public void printMemoryUsage() {
        Runtime rt = Runtime.getRuntime();
        double total = rt.totalMemory() / 1000000.0;
        double free = rt.freeMemory() / 1000000.0;
        System.out.println("Memory after test: " + (total - free) + " MB used / " + total + " MB total");
    }

    public RenameParams renameParams(String relativePath, int line, int column, String newName) {
        return new RenameParams(textDocumentPosition(relativePath, line, column).getTextDocument(),
                                textDocumentPosition(relativePath, line, column).getPosition(), newName);
    }

    public CompletionParams completionParams(String relativePath, int line, int column) {
        String file = workspaceRoot.resolve(relativePath).toString();
        TextDocumentIdentifier fileId = new TextDocumentIdentifier(file);
        Position position = position(line, column);
        return new CompletionParams(fileId, position);
    }

    public TextDocumentPositionParams textDocumentPosition(String relativePath, int line, int column) {
        String file = workspaceRoot.resolve(relativePath).toString();
        TextDocumentIdentifier fileId = new TextDocumentIdentifier(file);
        Position position = position(line, column);
        return new TextDocumentPositionParams(fileId, position);
    }

    public Position position(int line, int column) {
        return new Position(line - 1, column - 1);
    }

    public Range range(int startLine, int startColumn, int endLine, int endColumn) {
        return new Range(position(startLine, startColumn), position(endLine, endColumn));
    }

    public String uri(String relativePath) {
        return workspaceRoot.resolve(relativePath).toUri().toString();
    }

    public ReferenceParams referenceParams(String relativePath, int line, int column) {
        return new ReferenceParams(new TextDocumentIdentifier(uri(relativePath)), position(line, column), new ReferenceContext(true));
    }

    public void open(String relativePath) {
        Path file = workspaceRoot.resolve(relativePath);
        try{
        String content =new String(Files.readAllBytes(file));
            TextDocumentItem document = new TextDocumentItem(uri(relativePath), "Kotlin", 0, content);
        languageServer.getTextDocumentService().didOpen(new DidOpenTextDocumentParams(document));

            }catch(Exception e){

            }
            }

    public void replace(String relativePath, int line, int character, String oldText, String newText) {
        Range range = new Range(position(line, character), position(line, character + oldText.length()));
        TextDocumentContentChangeEvent edit = new TextDocumentContentChangeEvent(range, newText);
        VersionedTextDocumentIdentifier doc = new VersionedTextDocumentIdentifier(uri(relativePath), version++);
        languageServer.getTextDocumentService().didChange(new DidChangeTextDocumentParams(doc, List.of(edit)));
    }

    // LanguageClient functions

    @Override
    public void publishDiagnostics(PublishDiagnosticsParams diagnostics) {
        this.diagnostics = diagnostics.getDiagnostics();
    }

    @Override
    public CompletableFuture<MessageActionItem> showMessageRequest(ShowMessageRequestParams request) {
        System.out.println(request.toString());
        return null;
    }

    @Override
    public void telemetryEvent(Object object) {
        System.out.println(object.toString());
    }

    @Override
    public void logMessage(MessageParams message) {
        printMessage(message);
    }

    @Override
    public void showMessage(MessageParams message) {
        printMessage(message);
    }

    private void printMessage(MessageParams message) {
        System.out.println("[" + message.getType() + "] " + message.getMessage());
    }

    public abstract Path testResourcesRoot();

    private int version = 1;

}

but i get java.util.concurrent.TimeoutException: Unable to connect language server