Closed N1k145 closed 1 year ago
Do you have a log or know what the message was that caused the exception?
I tried running the testsuite with Java 17 and nothing failed.
Without more information I can't quite tell, but it looks to me like the Java code is trying to send a result (ResponseMessage) back to the other end and that message's result is of type CompletableFuture
, which isn't really a valid type to serialize. It may work with the add-opens because you end up with the CompletableFuture
's result
field in the output.
That said, I could actually reproduce this, but not with any standard LSP, but with some custom server code (by adapting IntegrationTest).
public static interface MyServerIssue680 {
@JsonRequest
CompletableFuture<Object> askServer(MyParam param);
}
public static class MyServerIssue680Impl implements MyServerIssue680 {
private Object innerMethodDoingTheWork(MyParam param) {
return CompletableFuture.completedFuture(param);
}
@Override
public CompletableFuture<Object> askServer(MyParam param) {
return CompletableFuture.completedFuture(innerMethodDoingTheWork(param));
}
};
@Test
public void testResponseIssue680() 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();
MyServerIssue680 server = new MyServerIssue680Impl();
Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
Assert.assertEquals("Content-Length: 63" + CRLF + CRLF
+ "{\"jsonrpc\":\"2.0\",\"id\":\"42\",\"result\":{\"result\":{\"value\":\"bar\"}}}",
out.toString());
}
protected String getHeader(int contentLength) {
StringBuilder headerBuilder = new StringBuilder();
headerBuilder.append(CONTENT_LENGTH_HEADER).append(": ").append(contentLength).append(CRLF);
headerBuilder.append(CRLF);
return headerBuilder.toString();
}
On Java 11 that passes, on Java 17 (without the --add-opens) it fails with a nearly identical stack trace.
To me that make sense as a CompletableFuture cannot be returned over the JSON-RPC link. You can see there is an issue in the JSON itself as it has a duplicated/nested result
field:
{
"jsonrpc": "2.0",
"id": "42",
"result": {
"result": {
"value": "bar"
}
}
}
Does the above describe your scenario? If so, it sounds like there is a bug report that should be filed with the project that has LSP4J integrated into it.
@jonahgraham thank for looking into it, and sorry for wasting your time. We found the issue in our integration. We were returning the Completable Future as a result of a command execution, which was actually executing the command and not the result of the Future.
Hey, I'm getting a similar issue to #674 using 0.15.0 running on Java 17 in the current eclipse release (2022-09).
Adding
--add-opens java.base/java.util.concurrent=ALL-UNNAMED
fixes this for now, but that's of course not a long time solution.