I've had some problems setting up an LSP server with Neovim. I think maybe some of my problems came from path clashes with nix. Now I've got it working, here's a note of the config.

Hopefully it will help some future visitor, and there's a very good chance one of those future visitors is me. 😅

Neovim's LSP Config

I'm using the lspconfig project. Here's the Java-specific part of the config:

lspconfig.jdtls.setup({
    cmd = {
        'nix',
        'develop',
        '--command',
        'jdtls',
    },

    init_options = {
        settings = {
            java = {
                imports = {
                    gradle = {
                        enabled = true,
                        wrapper = {
                            enabled = true,
                            -- Note the nested table here. This is really important.
                            -- `checksums` is an array of objects, which in lua translates to a table of tables.
                            checksums = {
                                {
                                    sha256 = '7d3a4ac4de1c32b59bc6a4eb8ecb8e612ccd0cf1ae1e99f66902da64df296172',
                                    allowed = true,
                                },
                            },
                        },
                    },
                },
            },
        },
    },
})

Note the cmd is running jdtls through nix. Also note that the SHA256 may need updating depending on which versions of everything you're using. The jdtls is Eclipse's Java language server.

Nix's flake.nix

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/25.05";
    utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, utils }:
    utils.lib.eachDefaultSystem (system:
      let
        pkgs = import nixpkgs {
          inherit system;
          overlays = [ ];
        };
      in
      {
        devShell =
          with pkgs;
          mkShell {
            buildInputs = [
              jdk21
              jdt-language-server

              (writeShellScriptBin "run" ''
                set -e
                ./gradlew bootRun
              '')
            ];

            JAVA_HOME = jdk21;
          };
      });
}

(The writeShellScriptBin part isn't necessary for this, but I'm leaving it in because it might be an interesting bonus tip.)

Gradle's build.gradle.kts

Getting the JDK versions to agree between Nix and Gradle is important:

...

java {
	toolchain {
		languageVersion = JavaLanguageVersion.of(21)
	}
}

...