spring-projects / sts4

The next generation of tooling for Spring Boot, including support for Cloud Foundry manifest files, Concourse CI pipeline definitions, BOSH deployment manifests, and more... - Available for Eclipse, Visual Studio Code, and Theia
https://spring.io/tools
Eclipse Public License 1.0
870 stars 203 forks source link

[refactoring] converting a simple rest service guide to Spring Boot 3 fails #867

Closed martinlippert closed 1 year ago

martinlippert commented 1 year ago

Converting a standard Rest Service guide to Spring Boot 3 using the OpenRewrite recipes fails with:

java.lang.reflect.InvocationTargetException
    at org.springframework.tooling.boot.ls.commands.RewriteRefactoringsHandler.lambda$10(RewriteRefactoringsHandler.java:133)
    at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:122)
Caused by: java.util.concurrent.ExecutionException: org.eclipse.lsp4j.jsonrpc.ResponseErrorException: Internal error.
    at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:396)
    at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2073)
    at org.springframework.tooling.boot.ls.commands.RewriteRefactoringsHandler.lambda$10(RewriteRefactoringsHandler.java:130)
    ... 1 more
Caused by: org.eclipse.lsp4j.jsonrpc.ResponseErrorException: Internal error.
    at org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.handleResponse(RemoteEndpoint.java:209)
    at org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.consume(RemoteEndpoint.java:193)
    at org.eclipse.lsp4e.LanguageServerWrapper.lambda$3(LanguageServerWrapper.java:286)
    at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.handleMessage(StreamMessageProducer.java:194)
    at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.listen(StreamMessageProducer.java:94)
    at org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor.run(ConcurrentMessageProcessor.java:113)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:833)

The language server output doesn't show anything, no exception and no other error message related to this.

BoykoAlex commented 1 year ago

Yes, I noticed this briefly while upgrading petclinic to 3.0. Thought about giving 4.16.1 a -1 because of this but then I stopped seeing this error and no else from those testing the build complained. If I can reproduce this reliably with Rest Service Guide I'd be happy to get to the bottom of this.

BoykoAlex commented 1 year ago

@martinlippert did you have POM file opened while upgrading? If yes, switch off XML Language Server and try again I suspect that the errors might go away... Also before bringing up the rewrite recipes selector dialog project contents need to be saved - I'll address this.

martinlippert commented 1 year ago

Yes, that indeed makes the error go away, but I am wondering what exactly triggers this error. Will look more into this, I guess.

martinlippert commented 1 year ago

This seems to be the error message that causes the exception:

[t=1668968235533] org.eclipse.wildwebdeveloper.xml to LSP4E:
{"jsonrpc":"2.0","id":"10","error":{"code":-32603,"message":"Internal error.","data":"java.lang.RuntimeException: java.lang.reflect.InvocationTargetException\n\tat org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint.lambda$null$0(GenericEndpoint.java:67)\n\tat org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint.request(GenericEndpoint.java:120)\n\tat org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.handleRequest(RemoteEndpoint.java:261)\n\tat org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.consume(RemoteEndpoint.java:190)\n\tat org.eclipse.lemminx.commons.ParentProcessWatcher.lambda$apply$0(ParentProcessWatcher.java:143)\n\tat org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.handleMessage(StreamMessageProducer.java:194)\n\tat org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.listen(StreamMessageProducer.java:94)\n\tat org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor.run(ConcurrentMessageProcessor.java:113)\n\tat java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)\n\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)\n\tat java.base/java.lang.Thread.run(Thread.java:833)\nCaused by: java.lang.reflect.InvocationTargetException\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)\n\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n\tat java.base/java.lang.reflect.Method.invoke(Method.java:568)\n\tat org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint.lambda$null$0(GenericEndpoint.java:65)\n\t... 12 more\nCaused by: org.eclipse.lsp4j.jsonrpc.ResponseErrorException: No command handler for the command: sts/rewrite/execute\n\tat org.eclipse.lemminx.XMLWorkspaceService.executeCommand(XMLWorkspaceService.java:55)\n\t... 17 more\n"}}

It looks like the command to execute the rewrite recipes is being sent to the XML language server:

[t=1668968235481] LSP4E to org.eclipse.wildwebdeveloper.xml:
{"jsonrpc":"2.0","id":"10","method":"workspace/executeCommand","params":{"command":"sts/rewrite/execute","arguments":...
martinlippert commented 1 year ago

In addition that it looks to me like the message that is being sent to the language server to execute the command is extremely long (more than 500k (!)). So it looks like we need to investigate why this message is being sent to the XML language server and why this message is so long.

BoykoAlex commented 1 year ago

@martinlippert good finds... I think I understand why the command goes out to XML LS when pom is opened. I think it is because of this:

                List<@NonNull LanguageServer> usedLanguageServers = LanguageServiceAccessor
                        .getActiveLanguageServers(serverCapabilities -> true);

Instead i plan to use LanguageServerRegistry to find the LS definition for id and then find the exact language server wrapper with the help of LanguageServerWrapper getLSWrapper(IProject project, LanguageServerDefinition serverDefinition) find the exact boot ls wrapper and if it's active execute the command on just that language server.

The long message issue... this is due to me sending recipe descriptors for the selected recipes... Recipe descriptor is ane exact data required to create a recipe on the server side, i.e description, name, parameters. Although i think 500Kb is a bit too much even for this data...

BoykoAlex commented 1 year ago

I limited command execution only to Boot LS with this: dd2f60ad914db564be066d1d8f16b8e8b847dc18 If 500Kb JSON parameter for the command can go to a separate issue (seems lower priority) then we try closing this one

martinlippert commented 1 year ago

I created a new issue for the message size issue: https://github.com/spring-projects/sts4/issues/897

martinlippert commented 1 year ago

Tested this with the latest nightly build, looks great. Closing this one as fixed.