Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java Support via coc.nvim #3

Closed
tbo opened this issue Dec 19, 2018 · 24 comments
Closed

Java Support via coc.nvim #3

tbo opened this issue Dec 19, 2018 · 24 comments

Comments

@tbo
Copy link

tbo commented Dec 19, 2018

The Readme mentions, that java support could be gained by integrating something like ycmd. I would propose using coc.nvim for this instead. It has much better language support and even offers bundled language servers. The java extension for coc should already contain a working DAP Server. It is part of eclipse.jdt.ls.

@puremourning
Copy link
Owner

As a core maintainer of YCM/ycmd, and author of the LSP integration in ycmd, it just makes more sense for me to use that.

I hadn't seen coc before. It's not obvious what advantage it would have in terms of integrating with jdt.ls over what I could do with YCM, but I will take a look.

TBH, reverse engineering the java debug plugin is proving to be pretty tricky, so java support is probably a way off either ways.

@puremourning
Copy link
Owner

For the record the DAP server is not part of jdt.ls. It's actually an extension bundle that is contributed in the Microsoft/vscode-java-debug VSCode extension, which ultimately boils down to the Microsoft/java-debug-server.

This then does things with VSCode's commands, and LSP's executeCommand abomination, which I have yet to fully get my head around.

@tbo
Copy link
Author

tbo commented Dec 19, 2018

For the record the DAP server is not part of jdt.ls. It's actually an extension bundle that is contributed in the Microsoft/vscode-java-debug VSCode extension, which ultimately boils down to the Microsoft/java-debug-server.

You are right. I should have read the whole thread.

@puremourning
Copy link
Owner

Well, as it happens I have made it work (sort of) with jdt.ls/java debug server without any hard-dependency on the mechanism used for starting the debug server.

vimspector asks the user what port to connect to and does not itself initiate jdt.ls's startDebugSession command.

In my fork of ycmd I have made it possible to send this command to the jdt.ls within ycmd and voila, java debugging works!

screenshot 2018-12-20 at 00 15 19

I haven't pushed this yet, but I'm quite pleased how simple it turned out to be.

@tbo
Copy link
Author

tbo commented Dec 24, 2018

In my fork of ycmd I have made it possible to send this command to the jdt.ls within ycmd and voila, java debugging works!

Nice! Will ycmd be a hard requirement for this or could it be configured to use another LSP-Provider?

@puremourning
Copy link
Owner

As it stands, there is no dependency on anything. You just have to tell vimspector the port on which the debug adapter is listening. How to start up the debug adapter int his case is not handled by vimspector. It just happens that it is trivial for me to make a ycm command which starts the debug server and returns the port to use. here's a demo:

vimspector-ycm-java-debug-1

@puremourning
Copy link
Owner

I would like to improve the workflow for firing up the adapter etc, but for now I would declare this "supported" by 14603ae so closing this issue (for now)

@tbo
Copy link
Author

tbo commented Dec 28, 2018

@puremourning How exactly did you start the debug plugin? I had a look at java-debug, but couldn't figure it out.

@puremourning
Copy link
Owner

As you can see in my demo, i'm using a customised version of YouCompleteMe (actually ycmd) to send a custom command to the jdt.ls server.

Ultimately, the way the debug server is started is:

  • something, somewhere starts up a jdt.ls instance with the debug adapter "bundle" passed as an additional initialisation option, and connects to it. In my case, this is my fork of ycmd.
  • something provides the capability send a Language Server Protocol 'executeCommand' message to that jdt.ls instance (In my case, this is :YcmCompleter ExectuteCommand <arguments>)
  • you execute the LSP command java.execute.workspaceCommand with arguments [ 'vscode.java.startDebugSession' ] (In my case, this is :YcmCompleter ExectuteCommand vscode.java.startDebugSession, as in the above demo)

The result of this is a number (a port) which is the TCP port on which the debug adapter is now listening. This is passed to vimspector by setting adapters.<something>.port to "ask".

So you have to be able to execute this custom command implemented by jdt.ls and forwarded to the debug adapter plugin. Because that's the way it is designed. In VSCode, this is all done by the extensions collaborating within the VScode IDE. Vimspector doesn't have all of that (yet?) so it's all a bit manual.

@puremourning
Copy link
Owner

Feel free to contact me on gitter if you want more info.

@puremourning
Copy link
Owner

FWIW i actually use this regularly with my YCM and it works well.

@tbodt
Copy link

tbodt commented Jan 19, 2020

Just found https://github.com/georgewfraser/java-language-server, which includes a debug adapter that can be started independently of the language server.

@puremourning
Copy link
Owner

I think I tried it and found it didn’t work wel. But try it out. Let us know.

@puremourning
Copy link
Owner

I was able to get George Fraser's debugger working at a basic level, but it seems a lot less stable.

It requires that you start your process with the java debug port set, then attach to it.

I pushed a change to make it possible to install it, and update the example java project.

Here are some instructions for the vimspector example (in support/test/java/test_project):

  • cd to /path/to/vimspector/support/test/java/test_project
  • man compile
  • cd to /path/to/vimspector,
  • ./install_gadget.py --no-gadget-config --force-enable-javac
  • Put the following in /path/to/vimspector/gadgets/<os>/.gadgets.d/vscode-javac.json:
{
  "adapters": {
    "vscode-javac": {
      "attach": {
        "pidSelect": "none"
      }, 
      "command": [
        "${gadgetDir}/java-language-server/dist/debug_adapter_mac.sh"
      ], 
      "name": "vscode-javac", 
      "type": "vscode-javac"
    }
  }
}
  • cd /path/to/vimspector/support/test/java/test_project/target/classs
  • java -cp . -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=y com.vimspector.test.TestApplication
  • In vim, open /path/to/vimspector/support/test/java/src/main/java/com/vimspector/test/TestApplication.java and set a breakpoint on main
  • Press <F5> and select the Attach with vscode-javac option
  • When asked, enter 5005 as the debugPort

I tested it a bit and it crashed a lot.

@dansomething
Copy link

Is there a way to set the value for adapters.vscode-java.port at run time while starting a vimspector session instead of being prompted via the "ask" config option? And as an alternative to updating the json config file automatically before starting vimspector.

@puremourning
Copy link
Owner

can you be more specific ? I mean if you always use port 1234, then just put 1234 in the vimspector.json. If you have a shell command you can run to work out the port, use a variable e.g.

  "configurations": {
    "attach": {
      "variables": { 
        "port": {
          "shell": { "cmd": [ "your command here" ] }
        }
      }
    }
  }

@dansomething
Copy link

Sorry for not being more specific... It is definitely nice to use a random port to allow multiple sessions at the same time. I'd like to be able to take the result of the vscode.java.startDebugSession command and pass it to vimspector when starting it. I can already get that port value in viml now. I just have it printed to the screen and then I manually type in that value when prompted by vimspector. I'd like to streamline that a bit if possible. Let me know if I can add any more clarity to help out.

@puremourning
Copy link
Owner

I'd like to be able to take the result of the vscode.java.startDebugSession command and pass it to vimspector when starting it.

Ah yes, this is a pain and on my sort of background TODO list to do something better.

Unfortunately there's no way to "tell" Vimsector the DAP communication port at the moment. Please feel free to raise a new issue for that. PRs of course also welcome :)

@dansomething
Copy link

dansomething commented Jan 27, 2020

Ok, thanks for that clarification. I've opened the issue here #97. I'll dig through the code to see if its something I could tackle. I'd love to contribute if there's time, but python and viml are definitely not by forte. Definitely like where this plugin is heading. Thanks again!

@puremourning
Copy link
Owner

I replied. On reflection, it's trivial to do without changes.

@puremourning
Copy link
Owner

I have updated the README with instructions for using java with YCM:

https://github.com/puremourning/vimspector/#java

@oblitum
Copy link

oblitum commented Jul 23, 2020

Just to update the thread, @dansomething has nicely provided coc-java-debug to integrate with Vimspector.

@puremourning
Copy link
Owner

Cool

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants