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
878 stars 206 forks source link

Support for NeoVim #1128

Open oysandvik94 opened 1 year ago

oysandvik94 commented 1 year ago

Neovim has support for JDT language server: https://github.com/mfussenegger/nvim-jdtls

sts4 support would be a great addition. I tried reading through the docs myself, but I didn't see an obvious way, but if anyone has any good tips I can give it a try myself.

BoykoAlex commented 1 year ago

The only complication of Spring Boot LS adoption in clients other than VSCode and Eclipse would be supporting communication between Spring Boot LS and JDT LS via the client - messages described here: https://github.com/spring-projects/sts4/wiki/Developer-Manual-Java-Messages If the JDT LS is used in NeoVim then if JDT LS extension JARs are supported with NeoVim the comm between JDT LS and Spring Boot LS should work.

BoykoAlex commented 1 year ago

Almost forgot. The comm between JDT LS and Boot LS via the client requires some client code to be present.

For example classpath listener related comm (most important) requires message handling code on the client: https://github.com/spring-projects/sts4/blob/main/vscode-extensions/commons-vscode/src/classpath.ts

Here is more for Java language related stuff: https://github.com/spring-projects/sts4/blob/main/vscode-extensions/commons-vscode/src/java-data.ts

Besides this the JDT LS extension JARs must be supported. This is done in VSCode here: https://github.com/spring-projects/sts4/blob/main/vscode-extensions/vscode-spring-boot/package.json#L34 but for other clients likely this would implemented differently.

oysandvik94 commented 1 year ago

Thanks a lot, I'll experiment a little!

s1n7ax commented 12 months ago

@oysandvik94 Hello. I'm working on https://github.com/s1n7ax/nvim-java plugin. I just want painless Java experience in Neovim. As a developer who's working on Spring Boot for the most part, I would like to have this integrated right in to nvim-java. It would be awesome if you would like to contribute or if I can steal the progress you have made on this.

oysandvik94 commented 12 months ago

@s1n7ax I got a new keyboard and layout, so I had to learn typing and didn't really get past the initial research phase. This sounds like an awesome project though, so I'd love to contribute when I get some time again.

s1n7ax commented 12 months ago

@oysandvik94 I will give this a try then. I really hope the layout is Colemak and you would contribute. Thanks

martinlippert commented 11 months ago

@s1n7ax @oysandvik94 Let us know how things are going and if you need any help.

s1n7ax commented 11 months ago

@oysandvik94 Bit occupied with jdtls + neotest integration. I will start working on this after this is done.

s1n7ax commented 11 months ago

So far this is what I figured.

           ┌─────────────┐                     ┌────────────┐
           │             │                     │            │
           │    VSCode   ◄──────────┬──────────►   Neovim   │
           │             │          │          │            │
           └──▲──────────┘          │          └────────▲───┘
              │                     │                   │
              │                     │                   │
              │                     │                   │
              │                     │                   │
              │                     │                   │
              │                     │                   │
              │                     │                   │
              │    ┌────────────────┴────────────────┐  │
              │    │                                 │  │
              │    │   spring boot language server   │  │
              │    │                                 │  │
              │    └──────────────┬───▲──────────────┘  │
              │                   │   │                 │
              │                   │   │                 │
              │                   │   │                 │
              │                   │   │                 │
              │               ┌───▼───┴───┐             │
              ├───────────────┘           └─────────────┤
       ┌──────┴───────────────►   JDTLS   ◄─────────────┴────────────────┐
       │                      │           │                              │
       │                      └──▲──────▲─┘                              │
       │                         │      │                                │
       │                         │      │                                │
       │                         │      │                                │
       │                         │      │                                │
┌──────┴───────┐  ┌──────────────┤ ┌────┴─────────────────┐  ┌───────────┴───────────┐
│              │  │              │ │                      │  │                       │
│   java-test  │  │  java-debug  │ │  jdt-ls-commons.jar  │  │  jdt-ls-extension.jar │
│              │  │              │ │                      │  │                       │
└──────────────┘  └──────────────┘ └──────────────────────┘  └───────────────────────┘
BoykoAlex commented 11 months ago

If jdt-ls-commons.jar and jdt-ls-extension.jar are the JARs from Boot LS that are extensions of the JDT LS then these would be inside JDT LS process. These are essentially Eclipse bundles that are loaded inside of JDT LS process.

s1n7ax commented 11 months ago

I have few questions.

I added a mson.nvim registry to get the artifacts from sts4 vscode-spring-boot-1.50.0-RC.2.vsix

image

I have loaded them to jdtls just like vscode-java-test & vscode-java-debug jdtls plugins

image

However, I don't see any commands being added to jdtls with this plugin. By the look of classpath.ts, there should be sts.java.addClasspathListener workspace command. However, no new commands were added after the plugin load. Any idea why?

image

s1n7ax commented 11 months ago

Got it working. extension loading failed due to missing io.projectreactor.reactor-core.jar dep. I added all 4 jdtls extensions in the package.json

https://github.com/spring-projects/sts4/blob/cb4056d8c2a4c0a61f46f35f498b3bd2d94988e7/vscode-extensions/vscode-spring-boot/package.json#L35-L39

image

s1n7ax commented 11 months ago

Can someone help me with these..

  1. Do I need some kind of interface in Neovim for spring boot LS to communicate with jdtls?
  2. How to start the lspconfig language server?

In Neovim, nvim-lspconfig plugin provides the language server setup configurations. At the moment, there is no any such config for spring boot language server. Is there any documentation regarding the command & other configurations needed to run the language server.

For reference, following is the default configurations that's used to start the jdtls language server

https://github.com/neovim/nvim-lspconfig/blob/694aaec65733e2d54d393abf80e526f86726c988/lua/lspconfig/server_configurations/jdtls.lua#L91-L124

s1n7ax commented 10 months ago

I think the way we register commands for jdtls to execute is using vim.lsp.commands. All this is confusing tbh.

sapelkinAV commented 10 months ago

Can someone help me with these..

  1. Do I need some kind of interface in Neovim for spring boot LS to communicate with jdtls?
  2. How to start the lspconfig language server?

In Neovim, nvim-lspconfig plugin provides the language server setup configurations. At the moment, there is no any such config for spring boot language server. Is there any documentation regarding the command & other configurations needed to run the language server.

For reference, following is the default configurations that's used to start the jdtls language server

https://github.com/neovim/nvim-lspconfig/blob/694aaec65733e2d54d393abf80e526f86726c988/lua/lspconfig/server_configurations/jdtls.lua#L91-L124

I think yes. Few month ago I tried to configure emacs as ide for java and they did some integrations with sts4. https://github.com/emacs-lsp/lsp-java/blob/master/lsp-java-boot.el it's written in lisp, but I'm sure it can be understandable. As I understand they extracted language server as a jar and used some wrapper logic around communication with spring-ls.

I really hope you can do it. I wish you all luck in that bumpy road. I want to try neovim, it seems really cool editor and workflow. Only one thing stopping me to try is a lack of time to configure it by myself because of the learning curve. But if it will help you I will be happy)

s1n7ax commented 10 months ago

Hello, what could be the cause of this error? I tried this on jdk17.

[nix-shell:~/Workspace/demo]$ java -Dspring.lsp.client-port=5832 -Dserver.port=5832 -Dsts.lsp.client=vscode -jar /home/s1n7ax/Downloads/Test/spring-boot-language-server-1.2.0-201812201920.jar
08:38:38.391 [main] INFO  o.s.i.v.b.a.BootLanguagServerBootApp - Starting BootLanguagServerBootApp v1.2.0-SNAPSHOT on s1n7ax with PID 15313 (/home/s1n7ax/Downloads/Test/spring-boot-language-server-1.2.0-201812201920.jar started by s1n7ax in /home/s1n7ax/Workspace/demo)
08:38:38.392 [main] INFO  o.s.i.v.b.a.BootLanguagServerBootApp - No active profile set, falling back to default profiles: default
08:38:38.415 [main] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@44f75083: startup date [Thu Dec 28 08:38:38 IST 2023]; root of context hierarchy
08:38:38.566 [main] ERROR o.s.boot.SpringApplication - Application run failed
java.lang.IllegalStateException: Cannot load configuration class: org.springframework.ide.vscode.boot.app.BootLanguagServerBootApp
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:414)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurationClassPostProcessor.java:254)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:282)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:126)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:694)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:333)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265)
    at org.springframework.ide.vscode.boot.app.BootLanguagServerBootApp.main(BootLanguagServerBootApp.java:59)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
    at org.springframework.boot.loader.PropertiesLauncher.main(PropertiesLauncher.java:587)
Caused by: java.lang.ExceptionInInitializerError: null
    at org.springframework.context.annotation.ConfigurationClassEnhancer.newEnhancer(ConfigurationClassEnhancer.java:122)
    at org.springframework.context.annotation.ConfigurationClassEnhancer.enhance(ConfigurationClassEnhancer.java:110)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:403)
    ... 19 common frames omitted
Caused by: org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InaccessibleObjectException-->Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @20fa23c1
    at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:464)
    at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:336)
    at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:93)
    at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:91)
    at org.springframework.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
    at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
    at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
    at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
    at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:116)
    at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:291)
    at org.springframework.cglib.core.KeyFactory$Generator.create(KeyFactory.java:221)
    at org.springframework.cglib.core.KeyFactory.create(KeyFactory.java:174)
    at org.springframework.cglib.core.KeyFactory.create(KeyFactory.java:153)
    at org.springframework.cglib.proxy.Enhancer.<clinit>(Enhancer.java:73)
    ... 22 common frames omitted
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @20fa23c1
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(Unknown Source)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(Unknown Source)
    at java.base/java.lang.reflect.Method.checkCanSetAccessible(Unknown Source)
    at java.base/java.lang.reflect.Method.setAccessible(Unknown Source)
    at org.springframework.cglib.core.ReflectUtils$1.run(ReflectUtils.java:61)
    at java.base/java.security.AccessController.doPrivileged(Unknown Source)
    at org.springframework.cglib.core.ReflectUtils.<clinit>(ReflectUtils.java:52)
    at org.springframework.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:243)
    at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
    at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:329)
    ... 34 common frames omitted
08:38:38.567 [main] INFO  o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@44f75083: startup date [Thu Dec 28 08:38:38 IST 2023]; root of context hierarchy
s1n7ax commented 10 months ago

I couldn't find the spring-boot-language-server.jar why where in the vscode-spring-boot-1.51.0-RC.3.vsix Anyone know where I can find that?

I got the jar I used above from following comment https://github.com/spring-projects/sts4/issues/76#issuecomment-451175464

sapelkinAV commented 10 months ago

image

It seems language server is here, but it's not in a jar format. I tried to check it through intellij, and it's very likely this is the main language server itself. Still can't figure it out how it works in initialization through vscode.

BoykoAlex commented 10 months ago

It is exploded JAR. Launching the server would be java -cp <classpsth> org.springframework.ide.vscode.boot.app.BootLanguageServerBootApp In other words launch java main class with the classpath. See this for classpath: https://github.com/spring-projects/sts4/blob/main/vscode-extensions/commons-vscode/src/launch-util.ts#L267

JavaHello commented 6 months ago