summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNantha Sorubakanthan <nantha@mielota.com>2026-02-21 10:50:44 +0100
committerNantha Sorubakanthan <nantha@mielota.com>2026-02-21 10:50:44 +0100
commita37c916b42eded7e70d0e5975192ee85f1a8017f (patch)
tree1e267ce339ae508f162389193f87743296727259
parentd8380fbb2720795eb31c2db2caac7429e1128f9a (diff)
guide(neovim): guide to have a basic java ide with neovim
-rw-r--r--content/guide/neovim-as-a-java-ide.md156
-rw-r--r--static/guide/icon/neovim.pngbin0 -> 68045 bytes
2 files changed, 156 insertions, 0 deletions
diff --git a/content/guide/neovim-as-a-java-ide.md b/content/guide/neovim-as-a-java-ide.md
new file mode 100644
index 0000000..412a79d
--- /dev/null
+++ b/content/guide/neovim-as-a-java-ide.md
@@ -0,0 +1,156 @@
+---
+title: Neovim as a Java IDE
+date: 2026-02-21
+icon: neovim.png
+---
+
+## Préambule
+
+Most of the time, you can configure Neovim painlessly with a simple `vim.lsp.enable("some_lsp_server")`. And boom, autocompletion, go to definition. Everything works out of the box. But that's not the case with Java, you can't check the definition of classes from the `java`, `javafx` or whatever package that is outside of your project, and most of the time the language server takes forever to load up or simply doesn't start.
+
+To fix these issues, we will not enable `jdtls` from the `vim.lsp.enable` function, and we will use the `mfussenegger/nvim-jdtls` plugin.
+
+In this tutorial, I assume that you know how to download plugins and edit you `init.lua` file. You should also already have a completion plugin.
+
+## Versions
+
+I think that the version of `python`, `jdtls` and `nvim` might affect the accuracy of this tutorial. So I will give you the versions I use as a reference in case you encounter some bugs.
+
+```sh
+% nvim --version
+NVIM v0.11.6
+Build type: RelWithDebInfo
+LuaJIT 2.1.1767980792
+```
+
+```sh
+# jdtls
+jdt-language-server-1.55.0-202601131729.tar.gz
+```
+
+```sh
+% python3 --version
+Python 3.14.3
+```
+
+```sh
+% java --version
+openjdk 25.0.2 2026-01-20
+```
+
+## Downloading Java and jdtls
+
+### Java
+
+First of all, you should install OpenJDK. You should download the latest version (at the time being it's version 25, but 21 should work).
+
+### jdtls with pacman
+
+If you use `pacman` on your Linux distro it's really easy. Just build the AUR package :
+
+```sh
+git clone https://aur.archlinux.org/jdtls.git
+cd jdtls/
+makepkg -si
+```
+
+### jdtls without pacman
+
+On other distros, I do not know how to install jdtls with the 'official' way. I know you could download it with the [mason.nvim](https://github.com/mason-org/mason.nvim) plugin, but it will make you go through additional configuration steps. I prefer downloading `jdtls` and adding it to my `$PATH` myself.
+
+So first of all download the latest tarball.
+
+```sh
+baseurl="https://download.eclipse.org/jdtls/milestones"
+
+ver=$(
+ curl -s "$baseurl/" |
+ grep -oE '/jdtls/milestones/[0-9]+\.[0-9]+\.[0-9]+' |
+ awk -F/ '{print $4}' |
+ sort -V |
+ tail -n1
+)
+
+file=$(
+ curl -s "$baseurl/$ver/" |
+ grep -oE "jdt-language-server-${ver}-[0-9]+\.tar\.gz" |
+ head -n1
+)
+
+curl -fL "https://www.eclipse.org/downloads/download.php?file=/jdtls/milestones/1.56.0/$file" -o jdtls.tar.gz
+```
+
+You should now have a `jdtls.tar.gz` file in your current working directory. Do not untar it now.
+
+Next create those folders :
+
+```sh
+sudo mkdir -pv /usr/local/share/java/jdtls
+```
+
+And you can now extract the content of `jdtls.tar.gz` into `/usr/local/share/java/jdtls`.
+
+```sh
+sudo tar xf jdtls.tar.gz -C /usr/local/share/java/jdtls
+```
+
+Next create a symlink to the `jdtls` binary in your $PATH :
+
+```sh
+sudo ln -s --relative /usr/local/share/java/jdtls/bin/jdtls /usr/local/bin/jdtls
+```
+
+You have successfully installed jdtls !
+
+## Configuring Neovim
+
+First of all, install the [mfussenegger/nvim-jdtls](https://github.com/mfussenegger/nvim-jdtls) plugin with your neovim plugin manager.
+
+Then, DO NOT enable `jdtls` with the `vim.lsp.enable` function.
+
+Instead, append this at the end of your `init.lua` file.
+
+```lua
+vim.api.nvim_create_autocmd("FileType", {
+ pattern = "java",
+ callback = function(args)
+ local project_name = vim.fn.fnamemodify(vim.fn.getcwd(), ":p:h:t")
+ local workspace_dir = vim.fn.stdpath("data") ..
+ package.config:sub(1, 1) .. "jdtls-workspace" .. package.config:sub(1, 1) .. project_name
+
+ local config = {
+ name = "jdtls",
+ cmd = {
+ "jdtls",
+ "-data",
+ workspace_dir,
+ },
+
+ root_dir = vim.fs.root(0, { ".git", "gradlew", "mvnw" }),
+
+ -- Here you can configure eclipse.jdt.ls specific settings
+ -- See https://github.com/eclipse/eclipse.jdt.ls/wiki/Running-the-JAVA-LS-server-from-the-command-line#initialize-request
+ -- for a list of options
+ settings = {
+ java = {
+ }
+ },
+
+
+ -- This sets the `initializationOptions` sent to the language server
+ -- If you plan on using additional eclipse.jdt.ls plugins like java-debug
+ -- you'll need to set the `bundles`
+ --
+ -- See https://codeberg.org/mfussenegger/nvim-jdtls#java-debug-installation
+ --
+ -- If you don't plan on any eclipse.jdt.ls plugins you can remove this
+ init_options = {
+ bundles = {}
+ },
+ }
+ require('jdtls').start_or_attach(config)
+ end
+})
+```
+
+Now, if you restart Neovim, and open a Java file in a project that has a `.git`, `mvnw`, or `gradlew` file at the top level directory. jdtls should work out of the box and you will be able to use all it's lsp features.
diff --git a/static/guide/icon/neovim.png b/static/guide/icon/neovim.png
new file mode 100644
index 0000000..96e66b7
--- /dev/null
+++ b/static/guide/icon/neovim.png
Binary files differ