下面列出了怎么用org.eclipse.lsp4j.jsonrpc.Launcher的API类实例代码及写法,或者点击链接到github查看源代码。
private void createClientConnection(AsynchronousSocketChannel socketChannel) {
Injector injector = Guice.createInjector(getGLSPModule());
GsonConfigurator gsonConf = injector.getInstance(GsonConfigurator.class);
InputStream in = Channels.newInputStream(socketChannel);
OutputStream out = Channels.newOutputStream(socketChannel);
Consumer<GsonBuilder> configureGson = (GsonBuilder builder) -> gsonConf.configureGsonBuilder(builder);
Function<MessageConsumer, MessageConsumer> wrapper = Function.identity();
GLSPServer languageServer = injector.getInstance(GLSPServer.class);
Launcher<GLSPClient> launcher = Launcher.createIoLauncher(languageServer, GLSPClient.class, in, out, threadPool,
wrapper, configureGson);
languageServer.connect(launcher.getRemoteProxy());
launcher.startListening();
try {
SocketAddress remoteAddress = socketChannel.getRemoteAddress();
log.info("Started language server for client " + remoteAddress);
} catch (IOException ex) {
log.error("Failed to get the remoteAddress for the new client connection: " + ex.getMessage(), ex);
}
}
/**
* Launches {@link XMLLanguageServer} using asynchronous server-socket channel and makes it accessible through the JSON
* RPC protocol defined by the LSP.
*
* @param args standard launch arguments. may contain <code>--port</code> argument to change the default port 5008
*/
public void launch(String[] args) throws Exception {
AsynchronousServerSocketChannel _open = AsynchronousServerSocketChannel.open();
int _port = getPort(args);
InetSocketAddress _inetSocketAddress = new InetSocketAddress("0.0.0.0", _port);
final AsynchronousServerSocketChannel serverSocket = _open.bind(_inetSocketAddress);
while (true) {
final AsynchronousSocketChannel socketChannel = serverSocket.accept().get();
final InputStream in = Channels.newInputStream(socketChannel);
final OutputStream out = Channels.newOutputStream(socketChannel);
final ExecutorService executorService = Executors.newCachedThreadPool();
XMLLanguageServer languageServer = new XMLLanguageServer();
final Launcher<LanguageClient> launcher = Launcher.createIoLauncher(languageServer, LanguageClient.class,
in, out, executorService, (MessageConsumer it) -> {
return it;
});
languageServer.setClient(launcher.getRemoteProxy());
launcher.startListening();
}
}
public static void main(String[] args) {
List<String> arguments = Arrays.asList(args);
if (arguments.contains(HELP_PARAMETER)) {
System.out.println(HELP_MESSAGE);
} else if (arguments.contains(WEBSOCKET_PARAMETER)) {
int port = extractPort(arguments);
String hostname = extractHostname(arguments);
webSocketRunner = new WebSocketRunner();
String contextPath = extractContextPath(arguments);
webSocketRunner.runWebSocketServer(hostname, port, contextPath);
} else {
server = new CamelLanguageServer();
Launcher<LanguageClient> launcher = LSPLauncher.createServerLauncher(server, System.in, System.out);
server.connect(launcher.getRemoteProxy());
launcher.startListening();
}
}
private void run(XLanguageServerImpl languageServer, Builder<LanguageClient> lsBuilder, InputStream in,
OutputStream out) {
Launcher<LanguageClient> launcher = lsBuilder
.setInput(in)
.setOutput(out)
.create();
languageServer.connect(launcher.getRemoteProxy());
Future<Void> future = launcher.startListening();
N4jscConsole.println("LSP Server connected");
Futures.getUnchecked(future);
N4jscConsole.println("Shutdown connection to LSP client");
languageServer.getLSPExecutorService().shutdown();
}
@SuppressWarnings({"try", "FutureReturnValueIgnored"})
public static void main(String[] args) throws DeploymentException, InterruptedException {
LOGGER.info(" -- >>> TeiidDdlLanguageServerRunner.main()");
List<String> arguments = Arrays.asList(args);
if (arguments.contains(WEBSOCKET_PARAMETER)) {
LOGGER.info(" -- >>> Started Teiid LS as WEB SOCKET");
int port = extractPort(arguments);
String hostname = extractHostname(arguments);
String contextPath = extractContextPath(arguments);
try (TeiidDdlWebSocketRunner runner = new TeiidDdlWebSocketRunner(hostname, port, contextPath);) {
Thread.currentThread().join();
}
} else {
LOGGER.info(" -- >>> Started Teiid LS as JAVA SERVER");
server = new TeiidDdlLanguageServer(null);
Launcher<LanguageClient> launcher = LSPLauncher.createServerLauncher(server, System.in, System.out);
server.connect(launcher.getRemoteProxy());
launcher.startListening();
LOGGER.info(" -- >>> Teiid LS Started. launch listening started");
}
}
@Before
public void setUp() throws IOException {
this.client = mock(ExecuteCommandProposedClient.class);
PipedOutputStream clientWritesTo = new PipedOutputStream();
PipedInputStream clientReadsFrom = new PipedInputStream();
PipedInputStream serverReadsFrom = new PipedInputStream();
PipedOutputStream serverWritesTo = new PipedOutputStream();
serverWritesTo.connect(clientReadsFrom);
clientWritesTo.connect(serverReadsFrom);
this.closeables = new Closeable[] { clientWritesTo, clientReadsFrom, serverReadsFrom, serverWritesTo };
Launcher<JavaLanguageClient> serverLauncher = Launcher.createLauncher(new Object(), JavaLanguageClient.class, serverReadsFrom, serverWritesTo);
serverLauncher.startListening();
Launcher<LanguageServer> clientLauncher = Launcher.createLauncher(client, LanguageServer.class, clientReadsFrom, clientWritesTo);
clientLauncher.startListening();
this.clientConnection = serverLauncher.getRemoteProxy();
}
public void launch(String[] args) {
Injector injector = Guice.createInjector(getServerModule());
try (AsynchronousServerSocketChannel serverSocket = AsynchronousServerSocketChannel.open()
.bind(getSocketAddress(args))) {
LOG.info("Started server socket at " + getSocketAddress(args));
while (true) {
AsynchronousSocketChannel socketChannel = serverSocket.accept().get();
InputStream in = Channels.newInputStream(socketChannel);
OutputStream out = Channels.newOutputStream(socketChannel);
PrintWriter trace = getTrace(args);
boolean validate = shouldValidate(args);
LanguageServerImpl languageServer = injector.getInstance(LanguageServerImpl.class);
LOG
.info("Starting Xtext Language Server for client " + socketChannel.getRemoteAddress());
Launcher<LanguageClient> launcher = Launcher.createLauncher(languageServer, LanguageClient.class, in,
out, validate, trace);
languageServer.connect(launcher.getRemoteProxy());
launcher.startListening();
LOG.info("Xtext Language Server has been started.");
}
} catch (Throwable t) {
t.printStackTrace();
}
}
/**
* creates a proxy, delegating to a remote endpoint, forwarding to another remote endpoint, that delegates to an actual implementation.
* @param intf
* @param impl
* @return
* @throws IOException
*/
public <T> T wrap(Class<T> intf, T impl) {
PipedInputStream in1 = new PipedInputStream();
PipedOutputStream out1 = new PipedOutputStream();
Launcher<T> launcher1 = Launcher.createLauncher(impl, intf, in1, out1);
PipedInputStream in2 = new PipedInputStream();
PipedOutputStream out2 = new PipedOutputStream();
Launcher<T> launcher2 = Launcher.createLauncher(new Object(), intf, in2, out2);
try {
in1.connect(out2);
in2.connect(out1);
} catch (IOException e) {
throw new IllegalStateException(e);
}
launcher1.startListening();
launcher2.startListening();
return launcher2.getRemoteProxy();
}
@Test
public void testResponse() throws Exception {
String clientMessage = "{\"type\":\"request\","
+ "\"seq\":1,\n"
+ "\"command\":\"askServer\",\n"
+ " \"arguments\": { value: \"bar\" }\n"
+ "}";
String clientMessages = getHeader(clientMessage.getBytes().length) + clientMessage;
// create server side
ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
ByteArrayOutputStream out = new ByteArrayOutputStream();
MyServer server = new MyServer() {
@Override
public CompletableFuture<MyParam> askServer(MyParam param) {
return CompletableFuture.completedFuture(param);
}
};
Launcher<MyClient> serverSideLauncher = DebugLauncher.createLauncher(server, MyClient.class, in, out);
serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
Assert.assertEquals("Content-Length: 103\r\n\r\n" +
"{\"type\":\"response\",\"seq\":1,\"request_seq\":1,\"command\":\"askServer\",\"success\":true,\"body\":{\"value\":\"bar\"}}",
out.toString());
}
@Test public void testCanceled() throws Exception {
A a = new A() {
@Override
public void say(Param p) {
}
};
Launcher<A> launcher = DebugLauncher.createLauncher(a, A.class, new InputStream() {
@Override
public int read() throws IOException {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return '\n';
}
}, new ByteArrayOutputStream());
Future<?> startListening = launcher.startListening();
startListening.cancel(true);
Assert.assertTrue(startListening.isDone());
Assert.assertTrue(startListening.isCancelled());
}
@Test
public void testResponse1() throws Exception {
// create client message
String requestMessage = "{\"jsonrpc\": \"2.0\",\n"
+ "\"id\": \"42\",\n"
+ "\"method\": \"askServer\",\n"
+ "\"params\": { \"value\": \"bar\" }\n"
+ "}";
String clientMessage = getHeader(requestMessage.getBytes().length) + requestMessage;
// create server side
ByteArrayInputStream in = new ByteArrayInputStream(clientMessage.getBytes());
ByteArrayOutputStream out = new ByteArrayOutputStream();
MyServer server = new MyServerImpl();
Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
Assert.assertEquals("Content-Length: 52" + CRLF + CRLF
+ "{\"jsonrpc\":\"2.0\",\"id\":\"42\",\"result\":{\"value\":\"bar\"}}",
out.toString());
}
@Test
public void testResponse2() throws Exception {
// create client message
String requestMessage = "{\"jsonrpc\": \"2.0\",\n"
+ "\"id\": 42,\n"
+ "\"method\": \"askServer\",\n"
+ "\"params\": { \"value\": \"bar\" }\n"
+ "}";
String clientMessage = getHeader(requestMessage.getBytes().length) + requestMessage;
// create server side
ByteArrayInputStream in = new ByteArrayInputStream(clientMessage.getBytes());
ByteArrayOutputStream out = new ByteArrayOutputStream();
MyServer server = new MyServerImpl();
Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
Assert.assertEquals("Content-Length: 50" + CRLF + CRLF
+ "{\"jsonrpc\":\"2.0\",\"id\":42,\"result\":{\"value\":\"bar\"}}",
out.toString());
}
@Test
public void testEither() throws Exception {
// create client message
String requestMessage = "{\"jsonrpc\": \"2.0\",\n"
+ "\"id\": 42,\n"
+ "\"method\": \"askServer\",\n"
+ "\"params\": { \"either\": \"bar\", \"value\": \"foo\" }\n"
+ "}";
String clientMessage = getHeader(requestMessage.getBytes().length) + requestMessage;
// create server side
ByteArrayInputStream in = new ByteArrayInputStream(clientMessage.getBytes());
ByteArrayOutputStream out = new ByteArrayOutputStream();
MyServer server = new MyServerImpl();
Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
Assert.assertEquals("Content-Length: 65" + CRLF + CRLF
+ "{\"jsonrpc\":\"2.0\",\"id\":42,\"result\":{\"value\":\"foo\",\"either\":\"bar\"}}",
out.toString());
}
@Test
public void testEitherNull() throws Exception {
// create client message
String requestMessage = "{\"jsonrpc\": \"2.0\",\n"
+ "\"id\": 42,\n"
+ "\"method\": \"askServer\",\n"
+ "\"params\": { \"either\": null, \"value\": \"foo\" }\n"
+ "}";
String clientMessage = getHeader(requestMessage.getBytes().length) + requestMessage;
// create server side
ByteArrayInputStream in = new ByteArrayInputStream(clientMessage.getBytes());
ByteArrayOutputStream out = new ByteArrayOutputStream();
MyServer server = new MyServerImpl();
Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
Assert.assertEquals("Content-Length: 50" + CRLF + CRLF
+ "{\"jsonrpc\":\"2.0\",\"id\":42,\"result\":{\"value\":\"foo\"}}",
out.toString());
}
@Test
public void testValidationIssue2() throws Exception {
String requestMessage1 = "{\"jsonrpc\": \"2.0\",\n"
+ "\"id\": \"1\",\n"
+ "\"method\": \"askServer\",\n"
+ "\"params\": { \"value\": null, \"nested\": { \"value\": null } }\n"
+ "}";
String clientMessages = getHeader(requestMessage1.getBytes().length) + requestMessage1;
ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
ByteArrayOutputStream out = new ByteArrayOutputStream();
MyServer server = new MyServerImpl();
Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out, true, null);
serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
Assert.assertEquals("Content-Length: 379" + CRLF + CRLF
+ "{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"error\":{\"code\":-32600,\"message\":\"Multiple issues were found in \\u0027askServer\\u0027 request.\","
+ "\"data\":["
+ "{\"text\":\"The accessor \\u0027MyParam.getValue()\\u0027 must return a non-null value. Path: $.params.nested.value\",\"code\":-32602},"
+ "{\"text\":\"The accessor \\u0027MyParam.getValue()\\u0027 must return a non-null value. Path: $.params.value\",\"code\":-32602}"
+ "]}}",
out.toString());
}
@Test public void testCanceled() throws Exception {
A a = new A() {
@Override
public void say(Param p) {
}
};
Launcher<A> launcher = Launcher.createLauncher(a, A.class, new InputStream() {
@Override
public int read() throws IOException {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return '\n';
}
}, new ByteArrayOutputStream());
Future<?> startListening = launcher.startListening();
startListening.cancel(true);
Assert.assertTrue(startListening.isDone());
Assert.assertTrue(startListening.isCancelled());
}
public static void main(String[] args) {
GroovyLanguageServer server = new GroovyLanguageServer();
Launcher<LanguageClient> launcher = Launcher.createLauncher(server, LanguageClient.class, System.in,
System.out);
server.connect(launcher.getRemoteProxy());
launcher.startListening();
}
/**
* Launches {@link XMLLanguageServer} and makes it accessible through the JSON
* RPC protocol defined by the LSP.
*
* @param launcherFuture The future returned by
* {@link org.eclipse.lsp4j.jsonrpc.Launcher#startListening()}.
* (I'm not 100% sure how it meant to be used though, as
* it's undocumented...)
*/
public static Future<?> launch(InputStream in, OutputStream out) {
XMLLanguageServer server = new XMLLanguageServer();
Function<MessageConsumer, MessageConsumer> wrapper;
if ("false".equals(System.getProperty("watchParentProcess"))) {
wrapper = it -> it;
} else {
wrapper = new ParentProcessWatcher(server);
}
Launcher<LanguageClient> launcher = createServerLauncher(server, in, out, Executors.newCachedThreadPool(), wrapper);
server.setClient(launcher.getRemoteProxy());
return launcher.startListening();
}
private static void run(InputStream in, OutputStream out) throws Exception {
LanguageServerImpl server = new LanguageServerImpl();
Launcher<LanguageClient> serverLauncher = LSPLauncher.createServerLauncher(server, in, out);
((LanguageClientAware) server).connect(serverLauncher.getRemoteProxy());
serverLauncher.startListening();
while (true) {
try {
Thread.sleep(100000);
} catch (InterruptedException ex) {
//ignore
}
}
}
@Messages("LBL_Connecting=Connecting to language server")
public static void addBindings(FileObject root, int port, String... extensions) {
BaseProgressUtils.showProgressDialogAndRun(() -> {
try {
Socket s = new Socket(InetAddress.getLocalHost(), port);
LanguageClientImpl lc = new LanguageClientImpl();
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
Launcher<LanguageServer> launcher = LSPLauncher.createClientLauncher(lc, in, new OutputStream() {
@Override
public void write(int w) throws IOException {
out.write(w);
if (w == '\n')
out.flush();
}
});
launcher.startListening();
LanguageServer server = launcher.getRemoteProxy();
InitializeResult result = initServer(null, server, root);
LSPBindings bindings = new LSPBindings(server, result, null);
lc.setBindings(bindings);
workspace2Extension2Server.put(root, Arrays.stream(extensions).collect(Collectors.toMap(k -> k, v -> bindings)));
} catch (InterruptedException | ExecutionException | IOException ex) {
Exceptions.printStackTrace(ex);
}
}, Bundle.LBL_Connecting());
}
@Override
public CompletableFuture<Void> start(File rootPath) {
setStatus(STARTING);
this.client = new LSPClient(this.startupLogic);
this.rootPath = rootPath;
try {
var processedArgs = this.argumentPreprocessor.apply(this, new ArrayList<>(this.lspArgs));
var streamConnectionProvider = new LSPProvider(
() -> requestManager,
processedArgs,
serverPath.get());
streamConnectionProvider.start();
Launcher<LanguageServer> launcher =
Launcher.createLauncher(client, LanguageServer.class, streamConnectionProvider.getInputStream(), streamConnectionProvider.getOutputStream());
languageServer = launcher.getRemoteProxy();
client.connect(languageServer);
launcherFuture = launcher.startListening();
return (startingFuture = languageServer.initialize(getInitParams()).thenApply(res -> {
LOGGER.info("Started LSP");
requestManager = new DefaultRequestManager(this, languageServer, client, res.getCapabilities());
setStatus(STARTED);
requestManager.initialized(new InitializedParams());
setStatus(INITIALIZED);
return res;
}).thenRun(() -> LOGGER.info("Done starting LSP!")));
} catch (Exception e) {
LOGGER.error("Can't launch language server for project", e);
}
return CompletableFuture.runAsync(() -> {});
}
static <T> Launcher<T> createSocketLauncher(Object localService, Class<T> remoteInterface, SocketAddress socketAddress, ExecutorService executorService, Function<MessageConsumer, MessageConsumer> 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;
}
static <T> Launcher<T> createSocketLauncher(Object localService, Class<T> remoteInterface,
SocketAddress socketAddress, ExecutorService executorService,
Function<MessageConsumer, MessageConsumer> wrapper, InputStream inputStream, OutputStream outputStream)
throws IOException {
return Launcher.createIoLauncher(localService, remoteInterface, inputStream, outputStream, executorService,
wrapper);
}
public static void main(String[] args) throws Exception {
Injector injector = Guice.createInjector(new ServerModule());
LanguageServer languageServer = injector.getInstance(LanguageServer.class);
ServerSocketChannel serverSocket = ServerSocketChannel.open();
serverSocket.bind(new InetSocketAddress("localhost", 5007));
SocketChannel socketChannel = serverSocket.accept();
Launcher<LanguageClient> launcher = LSPLauncher.createServerLauncher(languageServer, Channels.newInputStream(socketChannel), Channels.newOutputStream(socketChannel), true, new PrintWriter(System.out));
launcher.startListening().get();
}
@Override
public void onOpen(Session session, EndpointConfig config) {
WebSocketLauncherBuilder<T> builder = new WebSocketLauncherBuilder<T>();
builder.setSession(session);
configure(builder);
Launcher<T> launcher = builder.create();
connect(builder.getLocalServices(), launcher.getRemoteProxy());
}
@Override
public Launcher<T> create() {
if (localServices == null)
throw new IllegalStateException("Local service must be configured.");
if (remoteInterfaces == null)
throw new IllegalStateException("Remote interface must be configured.");
MessageJsonHandler jsonHandler = createJsonHandler();
RemoteEndpoint remoteEndpoint = createRemoteEndpoint(jsonHandler);
addMessageHandlers(jsonHandler, remoteEndpoint);
T remoteProxy = createProxy(remoteEndpoint);
return createLauncher(null, remoteProxy, remoteEndpoint, null);
}
/**
* Create a new Launcher for a language server and an input and output stream.
*
* @param server - the server that receives method calls from the remote client
* @param in - input stream to listen for incoming messages
* @param out - output stream to send outgoing messages
*/
public static Launcher<LanguageClient> createServerLauncher(LanguageServer server, InputStream in, OutputStream out) {
return new Builder<LanguageClient>()
.setLocalService(server)
.setRemoteInterface(LanguageClient.class)
.setInput(in)
.setOutput(out)
.create();
}
/**
* Create a new Launcher for a language server and an input and output stream, and set up message validation and tracing.
*
* @param server - the server that receives method calls from the remote client
* @param in - input stream to listen for incoming messages
* @param out - output stream to send outgoing messages
* @param validate - whether messages should be validated with the {@link ReflectiveMessageValidator}
* @param trace - a writer to which incoming and outgoing messages are traced, or {@code null} to disable tracing
*/
public static Launcher<LanguageClient> createServerLauncher(LanguageServer server, InputStream in, OutputStream out,
boolean validate, PrintWriter trace) {
return new Builder<LanguageClient>()
.setLocalService(server)
.setRemoteInterface(LanguageClient.class)
.setInput(in)
.setOutput(out)
.validateMessages(validate)
.traceMessages(trace)
.create();
}
/**
* Create a new Launcher for a language server and an input and output stream. Threads are started with the given
* executor service. The wrapper function is applied to the incoming and outgoing message streams so additional
* message handling such as validation and tracing can be included.
*
* @param server - the server that receives method calls from the remote client
* @param in - input stream to listen for incoming messages
* @param out - output stream to send outgoing messages
* @param executorService - the executor service used to start threads
* @param wrapper - a function for plugging in additional message consumers
*/
public static Launcher<LanguageClient> createServerLauncher(LanguageServer server, InputStream in, OutputStream out,
ExecutorService executorService, Function<MessageConsumer, MessageConsumer> wrapper) {
return new Builder<LanguageClient>()
.setLocalService(server)
.setRemoteInterface(LanguageClient.class)
.setInput(in)
.setOutput(out)
.setExecutorService(executorService)
.wrapMessages(wrapper)
.create();
}
/**
* Create a new Launcher for a language client and an input and output stream.
*
* @param client - the client that receives method calls from the remote server
* @param in - input stream to listen for incoming messages
* @param out - output stream to send outgoing messages
*/
public static Launcher<LanguageServer> createClientLauncher(LanguageClient client, InputStream in, OutputStream out) {
return new Builder<LanguageServer>()
.setLocalService(client)
.setRemoteInterface(LanguageServer.class)
.setInput(in)
.setOutput(out)
.create();
}