This is the fourth part of a few tutorials on Java development with Neovim using the LazyVim setup.
This post assumes you have already read and applied all the steps of the first, second, and third parts.
You need Java installed (possibly 21), while Maven is optional.
I will use this Maven example during the tutorial: https://github.com/LorenzoBettini/maven-bank-example, part of my TDD book.
The final result of this series of tutorials can be found here: https://github.com/LorenzoBettini/lazyvim-java. The “main” branch always points to the latest blog post.
The end of this part is still the branch “fourth-blog-post”.
Currently, we cannot run/debug anything, i.e., not even tests. We need the “nvim-dap” (debugger adapter), which is optional in the LazyVim Java extra (see the documentation, https://www.lazyvim.org/extras/lang/java). If the “nvim-dap” is installed, the LazyVim Java extra automatically configures the corresponding mechanisms for Java. Instead of installing the single plugin, we use another extra: https://www.lazyvim.org/extras/dap/core, which also installs other dap-related goodies, including the UI. We install the extra in one of the documented ways. As done before, I’m using the “:LazyExtras” UI, searching for “dap.core” and installing it. Of course, then we need to restart Neovim.
When you enable this extra, Mason must install additional packages: “java-test” and “java-debugger-adapter”. They are installed automatically (but you have to wait for their installation the first time you start Neovim; as usual, you can check the installation status using the Mason UI, “:Mason”).
Running
These plugins are configured so that the Java LSP can detect Java files with the “main” method. Let’s open such a file (in this example, “Main.java”). To start the application (in debug mode, though in this first run, we haven’t set any breakpoint), the command to search for is “Run/Continue” (not “Run with args”). In fact, “continue” is meant to continue a program under debugging that has stopped due to a breakpoint. Still, it is ALSO meant to start a program if there’s no program under debugging (that’s the documented behavior of DAP). Such commands can be accessed as submenus with “<leader> d” (“d” is for “debug”):
Let’s start this program with “c”.
In the dialog that appears, we select the “Launch” configuration (remember that you can type to fuzzy select):
This example contains a single Java file with a “main” method. If, in your program, you have several Java files with the “main” method, the LSP will detect them all and, upon launching, will show a picker to select the one you want to run.
The program doesn’t do anything interesting besides creating an object, calling a few methods, and logging something on the console. It terminates quickly, so you might see a few additional windows (the UI changes) for a second and then return to the source code. The UI that quickly appeared and disappeared is the “Dap UI”. As shown in the menus above, you can manually toggle it back with “<leader> d u” (as usual, I change the color scheme so that some parts of the UI are more evident):
For the moment, since we did not do any debugging, the only interesting window is the one at the bottom-right, showing the console with the output of the program we have just run.
Running with arguments
Let’s use “Run with Args,” which allows us to pass command line arguments to the Java application.
This application does not do anything with the passed arguments. Let’s change the “main” to print the arguments on the console. For example, adding this line at the beginning:
1 |
System.out.println(Arrays.toString(args)); |
Select “<leader> d a”, and specify a few arguments:
We’ll see “[first, second, third]” in the console.
Custom launch configurations
Besides the automatically detected Java files with a “main” method, the LSP is configured to support VSCode launch configurations, which, by default, are searched for in the file at the root of the project “.vscode/launch.json”. The options for such files are similar to the ones found here: https://code.visualstudio.com/docs/java/java-debugging#_configuration-options, though the accepted JSON is not strictly the same, and some options might be different. The specific format accepted by Dap is documented in the Dap documentation (e.g., online at https://github.com/mfussenegger/nvim-dap/blob/master/doc/dap.txt or using the “:help dap-api”).
TIP: it might be a good moment to install the LazyVim JSON extra, as we have already seen before.
If you create in the root of the Java project the file “.vscode/launch.json”, i.e., “:e .vscode/launch.json”, the file is created with some initial contents:
1 2 3 4 5 6 7 8 9 10 11 |
{ "$schema": "https://raw.githubusercontent.com/mfussenegger/dapconfig-schema/master/dapconfig-schema.json", "version": "0.2.0", "configurations": [ { "type": "<adapter-name>", "request": "launch", "name": "Launch" } ] } |
For this example, I’m creating two additional launch configurations for passing some fixed arguments to the main file and another one that prompts the command line to pass:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
{ "$schema": "https://raw.githubusercontent.com/mfussenegger/dapconfig-schema/master/dapconfig-schema.json", "version": "0.2.0", "configurations": [ { "type": "java", "request": "launch", "name": "Launch Java with fixed arguments", "args": "one two three" }, { "type": "java", "request": "launch", "name": "Launch Java with arguments (prompt)", "args": "${input:myPrompt}" } ], "inputs": [ { "id": "myPrompt", "type": "promptString", "description": "argument: ", "default": "foobar" } ] } |
Note that since these launch configurations do not specify the Java class with the main (see the corresponding option if you want to do that), they work correctly only when your buffer contains a Java file with “main”.
Let’s open the “Main.java” file and try to run the program with “<leader> d c”: we get this selection dialog to choose the configuration (where the first two are as before, and the other ones are taken from the “launch.json” above):
If you select the configuration with the prompt, you get another pop-up dialog where you can insert the command line arguments. The dialog is pre-filled with the default value specified above, “foobar”:
That’s all for this post.
In the next post, we’ll learn how to debug a Java program from Neovim.