diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/LaunguageServerApp.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/LaunguageServerApp.java
index 3f4e51dd4..f62aef438 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/LaunguageServerApp.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/LaunguageServerApp.java
@@ -15,10 +15,16 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
+import java.net.InetSocketAddress;
import java.net.Socket;
+import java.net.SocketAddress;
+import java.nio.channels.AsynchronousServerSocketChannel;
+import java.nio.channels.AsynchronousSocketChannel;
+import java.nio.channels.Channels;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -31,6 +37,7 @@ import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.LanguageClientAware;
import org.eclipse.lsp4j.services.LanguageServer;
import org.springframework.ide.vscode.commons.languageserver.util.LoggingFormat;
+import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
/**
@@ -38,24 +45,44 @@ import org.springframework.ide.vscode.commons.languageserver.util.LoggingFormat;
* write to create suitable 'main' method to launch a language server.
*
* The easiest way to use this is to create your own static main method.
- * Then call this class's start method with a Provider as
+ * Then call this class's start method with a Provider as
* a argument.
*
* Alternatively, you can also subclass it and implement the abstract
* `createServer` method.
*
* @author Kris De Volder
+ * @author Martin Lippert
*/
public abstract class LaunguageServerApp {
- public static void start(Provider languageServerFactory) throws IOException {
+ private static final String STANDALONE_STARTUP = "standalone-startup";
+ private static final int SERVER_STANDALONE_PORT = 5007;
+
+ public static void start(Provider languageServerFactory) throws IOException, InterruptedException {
LaunguageServerApp app = new LaunguageServerApp() {
@Override
- protected LanguageServer createServer() {
+ protected SimpleLanguageServer createServer() {
return languageServerFactory.get();
}
};
- app.start();
+
+ if (System.getProperty(STANDALONE_STARTUP, "false").equals("true")) {
+ app.startAsServer();
+ }
+ else {
+ app.start();
+ }
+ }
+
+ public static void startAsServer(Provider languageServerFactory) throws IOException, InterruptedException {
+ LaunguageServerApp app = new LaunguageServerApp() {
+ @Override
+ protected SimpleLanguageServer createServer() {
+ return languageServerFactory.get();
+ }
+ };
+ app.startAsServer();
}
protected static class Connection {
@@ -112,7 +139,50 @@ public abstract class LaunguageServerApp {
}
}
- private static Connection connectToNode() throws IOException {
+ /**
+ * starts up the language server and let it listen for connections from the outside
+ * instead of connecting itself to an existing port or channel.
+ *
+ * This is meant for development only, to reduce turnaround times while working
+ * on the language server from within an IDE, so that you can start the language
+ * server right away in debug mode and let the vscode extension connect to that
+ * instance instead of vice versa.
+ *
+ * Source of inspiration:
+ * https://github.com/itemis/xtext-languageserver-example/blob/master/org.xtext.example.mydsl.ide/src/org/xtext/example/mydsl/ide/RunServer.java
+ */
+ public void startAsServer() throws IOException, InterruptedException {
+ LOG.info("Starting LS as standlone server");
+
+ Function wrapper = consumer -> {
+ MessageConsumer result = consumer;
+ return result;
+ };
+
+ SimpleLanguageServer languageServer = createServer();
+ Launcher launcher = createSocketLauncher(languageServer, STS4LanguageClient.class,
+ new InetSocketAddress("localhost", SERVER_STANDALONE_PORT), Executors.newCachedThreadPool(), wrapper);
+
+ languageServer.connect(launcher.getRemoteProxy());
+ Future> future = launcher.startListening();
+ while (!future.isDone()) {
+ Thread.sleep(10_000l);
+ }
+ }
+
+ private Launcher createSocketLauncher(Object localService, Class remoteInterface, SocketAddress socketAddress, ExecutorService executorService, Function wrapper) throws IOException {
+ AsynchronousServerSocketChannel serverSocket = AsynchronousServerSocketChannel.open().bind(socketAddress);
+ AsynchronousSocketChannel socketChannel;
+ try {
+ socketChannel = serverSocket.accept().get();
+ return Launcher.createIoLauncher(localService, remoteInterface, Channels.newInputStream(socketChannel), Channels.newOutputStream(socketChannel), executorService, wrapper);
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ private static Connection connectToNode() throws IOException {
String port = System.getProperty("server.port");
if (port != null) {
@@ -172,7 +242,7 @@ public abstract class LaunguageServerApp {
launcher.startListening().get();
}
- protected abstract LanguageServer createServer();
+ protected abstract SimpleLanguageServer createServer();
}
diff --git a/vscode-extensions/vscode-boot-java/src/main/java/org/springframework/ide/vscode/boot/java/Main.java b/vscode-extensions/vscode-boot-java/src/main/java/org/springframework/ide/vscode/boot/java/Main.java
index 73e1103bd..d8b545050 100644
--- a/vscode-extensions/vscode-boot-java/src/main/java/org/springframework/ide/vscode/boot/java/Main.java
+++ b/vscode-extensions/vscode-boot-java/src/main/java/org/springframework/ide/vscode/boot/java/Main.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016 Pivotal, Inc.
+ * Copyright (c) 2016, 2017 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -23,7 +23,7 @@ import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguage
*/
public class Main {
- public static void main(String[] args) throws IOException {
+ public static void main(String[] args) throws IOException, InterruptedException {
LaunguageServerApp.start(() -> {
JavaProjectFinder javaProjectFinder = BootJavaLanguageServer.DEFAULT_PROJECT_FINDER;
SimpleLanguageServer server = new BootJavaLanguageServer(javaProjectFinder);
diff --git a/vscode-extensions/vscode-boot-java/src/main/java/org/springframework/ide/vscode/boot/java/StartupServer.java b/vscode-extensions/vscode-boot-java/src/main/java/org/springframework/ide/vscode/boot/java/StartupServer.java
deleted file mode 100644
index 7ba13b8c7..000000000
--- a/vscode-extensions/vscode-boot-java/src/main/java/org/springframework/ide/vscode/boot/java/StartupServer.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2017 Pivotal, Inc.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Pivotal, Inc. - initial API and implementation
- *******************************************************************************/
-package org.springframework.ide.vscode.boot.java;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.channels.AsynchronousServerSocketChannel;
-import java.nio.channels.AsynchronousSocketChannel;
-import java.nio.channels.Channels;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.function.Function;
-
-import org.eclipse.lsp4j.jsonrpc.Launcher;
-import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
-import org.springframework.ide.vscode.commons.languageserver.STS4LanguageClient;
-import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
-import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
-
-/**
- * starts up the language server and let it listen for connections from the outside
- * instead of connecting itself to an existing port or channel.
- *
- * This is meant for development only, to reduce turnaround times while working
- * on the language server from within an IDE, so that you can start the language
- * server right away in debug mode and let the vscode extension connect to that
- * instance instead of vice versa.
- *
- * Source of inspiration:
- * https://github.com/itemis/xtext-languageserver-example/blob/master/org.xtext.example.mydsl.ide/src/org/xtext/example/mydsl/ide/RunServer.java
- *
- * @author Martin Lippert
- */
-public class StartupServer {
-
- public static void main(String[] args) throws InterruptedException, IOException {
-
- JavaProjectFinder javaProjectFinder = BootJavaLanguageServer.DEFAULT_PROJECT_FINDER;
- SimpleLanguageServer languageServer = new BootJavaLanguageServer(javaProjectFinder);
-
- Function wrapper = consumer -> {
- MessageConsumer result = consumer;
- return result;
- };
-
- Launcher launcher = createSocketLauncher(languageServer, STS4LanguageClient.class, new InetSocketAddress("localhost", 5007), Executors.newCachedThreadPool(), wrapper);
-
- languageServer.connect(launcher.getRemoteProxy());
- Future> future = launcher.startListening();
- while (!future.isDone()) {
- Thread.sleep(10_000l);
- }
- }
-
- private static Launcher createSocketLauncher(Object localService, Class remoteInterface, SocketAddress socketAddress, ExecutorService executorService, Function wrapper) throws IOException {
- AsynchronousServerSocketChannel serverSocket = AsynchronousServerSocketChannel.open().bind(socketAddress);
- AsynchronousSocketChannel socketChannel;
- try {
- socketChannel = serverSocket.accept().get();
- return Launcher.createIoLauncher(localService, remoteInterface, Channels.newInputStream(socketChannel), Channels.newOutputStream(socketChannel), executorService, wrapper);
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
- }
- return null;
- }
-
-}
diff --git a/vscode-extensions/vscode-boot-properties/src/main/java/org/springframework/ide/vscode/boot/Main.java b/vscode-extensions/vscode-boot-properties/src/main/java/org/springframework/ide/vscode/boot/Main.java
index 0b3391015..e77b0f41e 100644
--- a/vscode-extensions/vscode-boot-properties/src/main/java/org/springframework/ide/vscode/boot/Main.java
+++ b/vscode-extensions/vscode-boot-properties/src/main/java/org/springframework/ide/vscode/boot/Main.java
@@ -29,7 +29,7 @@ import org.springframework.ide.vscode.commons.util.text.IDocument;
*/
public class Main {
- public static void main(String[] args) throws IOException {
+ public static void main(String[] args) throws IOException, InterruptedException {
LaunguageServerApp.start(() -> {
JavaProjectFinder javaProjectFinder = BootPropertiesLanguageServer.DEFAULT_PROJECT_FINDER;
DefaultSpringPropertyIndexProvider indexProvider = new DefaultSpringPropertyIndexProvider(javaProjectFinder);
diff --git a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/Main.java b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/Main.java
index bd8631914..af1006194 100644
--- a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/Main.java
+++ b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/Main.java
@@ -19,7 +19,7 @@ import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguage
public class Main {
SimpleLanguageServer server = new ConcourseLanguageServer();
- public static void main(String[] args) throws IOException {
+ public static void main(String[] args) throws IOException, InterruptedException {
LaunguageServerApp.start(ConcourseLanguageServer::new);
}
}
diff --git a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/Main.java b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/Main.java
index e072d659e..4c1ae9c84 100644
--- a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/Main.java
+++ b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/Main.java
@@ -18,7 +18,7 @@ import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguage
public class Main {
SimpleLanguageServer server = new ManifestYamlLanguageServer();
- public static void main(String[] args) throws IOException {
+ public static void main(String[] args) throws IOException, InterruptedException {
LaunguageServerApp.start(ManifestYamlLanguageServer::new);
}
}