← 返回首页
feat(tools): allow specifying paths instead of auto installing (#488) · nvim-java/nvim-java@9e8b842 · GitHub
Skip to content

Navigation Menu

Toggle navigation
Sign in
Appearance settings
Search or jump to...

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Resetting focus

Commit 9e8b842

Browse files
authored
feat(tools): allow specifying paths instead of auto installing (#488)
* feat(config): allow configuring paths to the tools * fix(jdtls): scope config cache by root * fix(jdtls): support os config fallback * feat(tools): address code review remarks - declare manage at module scope once and reuse - throw if plugin config is inconsistent - update docs to explain path parameter has no effect when tool is disabled * fix PR check errors
1 parent dcf18d8 commit 9e8b842

14 files changed

Lines changed: 425 additions & 64 deletions

File tree

‎.luacheckrc‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,9 @@ read_globals = {
1616
ignore = {
1717
'212/self',
1818
}
19+
files['tests/specs/pkgm_resolve_spec.lua'] = {
20+
globals = {
21+
'vim.notify',
22+
},
23+
}
1924
max_line_length = false

‎README.md‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,33 +336,44 @@ require('java').setup({
336336
-- JDTLS configuration
337337
jdtls = {
338338
version = '1.43.0',
339+
path = nil,
340+
auto_install = true,
339341
},
340342

341343
-- Extensions
342344
lombok = {
343345
enable = true,
344346
version = '1.18.40',
347+
path = nil,
348+
auto_install = true,
345349
},
346350

347351
java_test = {
348352
enable = true,
349353
version = '0.40.1',
354+
path = nil,
355+
auto_install = true,
350356
},
351357

352358
java_debug_adapter = {
353359
enable = true,
354360
version = '0.58.2',
361+
path = nil,
362+
auto_install = true,
355363
},
356364

357365
spring_boot_tools = {
358366
enable = true,
359367
version = '1.55.1',
368+
path = nil,
369+
auto_install = true,
360370
},
361371

362372
-- JDK installation
363373
jdk = {
364374
auto_install = true,
365375
version = '17',
376+
path = nil,
366377
},
367378

368379
-- Logging
@@ -377,6 +388,21 @@ require('java').setup({
377388
})
378389
```
379390

391+
Set `path` when a tool is managed externally. When `path` is set, nvim-java
392+
uses that path and does not install the tool. Set
393+
`auto_install = false` on a tool to fail instead of downloading when no path is
394+
configured. Note: `path` has no effect when the tool is disabled
395+
(`enable = false`) — the tool is simply not loaded.
396+
397+
Path meanings:
398+
399+
- `jdtls.path`: directory containing `plugins/` and platform `config_*`
400+
directories
401+
- `lombok.path`: path to `lombok.jar`
402+
- `java_test.path`, `java_debug_adapter.path`, `spring_boot_tools.path`: VS Code
403+
extension root containing `package.json`
404+
- `jdk.path`: JDK home containing `bin/java`
405+
380406
</details>
381407

382408
## :golf: Architecture

‎doc/nvim-java.txt‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,33 +349,44 @@ want, following options are available:
349349
-- JDTLS configuration
350350
jdtls = {
351351
version = '1.43.0',
352+
path = nil,
353+
auto_install = true,
352354
},
353355

354356
-- Extensions
355357
lombok = {
356358
enable = true,
357359
version = '1.18.40',
360+
path = nil,
361+
auto_install = true,
358362
},
359363

360364
java_test = {
361365
enable = true,
362366
version = '0.40.1',
367+
path = nil,
368+
auto_install = true,
363369
},
364370

365371
java_debug_adapter = {
366372
enable = true,
367373
version = '0.58.2',
374+
path = nil,
375+
auto_install = true,
368376
},
369377

370378
spring_boot_tools = {
371379
enable = true,
372380
version = '1.55.1',
381+
path = nil,
382+
auto_install = true,
373383
},
374384

375385
-- JDK installation
376386
jdk = {
377387
auto_install = true,
378388
version = '17',
389+
path = nil,
379390
},
380391

381392
-- Logging
@@ -390,6 +401,21 @@ want, following options are available:
390401
})
391402
<
392403

404+
Set `path` when a tool is managed externally. When `path` is set, nvim-java
405+
uses that path and does not install the tool. Set
406+
`auto_install = false` on a tool to fail instead of downloading when no path is
407+
configured. Note: `path` has no effect when the tool is disabled
408+
(`enable = false`) — the tool is simply not loaded.
409+
410+
Path meanings:
411+
412+
- `jdtls.path`: directory containing `plugins/` and platform `config_*`
413+
directories
414+
- `lombok.path`: path to `lombok.jar`
415+
- `java_test.path`, `java_debug_adapter.path`, `spring_boot_tools.path`: VS Code
416+
extension root containing `package.json`
417+
- `jdk.path`: JDK home containing `bin/java`
418+
393419

394420
ARCHITECTURE *nvim-java-architecture*
395421

‎lua/java-core/ls/servers/jdtls/cmd.lua‎

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
local List = require('java-core.utils.list')
22
local path = require('java-core.utils.path')
3-
local Manager = require('pkgm.manager')
43
local system = require('java-core.utils.system')
54
local log = require('java-core.utils.log2')
65
local err = require('java-core.utils.errors')
76
local java_version_map = require('java-core.constants.java_version')
87
local lsp_utils = require('java-core.utils.lsp')
98
local str = require('java-core.utils.str')
9+
local resolver = require('pkgm.resolve')
1010

1111
local M = {}
1212

@@ -23,7 +23,7 @@ function M.get_cmd(config)
2323
-- system java. So as a workaround, we use the absolute path to java instead
2424
-- So following check is not needed when we have auto_install set to true
2525
-- @see https://github.com/neovim/neovim/issues/36818
26-
if not config.jdk.auto_install then
26+
if not config.jdk.auto_install and not config.jdk.path then
2727
M.validate_java_version(config, lsp_config.cmd_env)
2828
end
2929

@@ -44,23 +44,16 @@ end
4444
---@return java-core.List
4545
function M.get_jvm_args(config)
4646
local use_lombok = config.lombok.enable
47-
local jdtls_root = Manager:get_install_dir('jdtls', config.jdtls.version)
48-
local jdtls_config = path.join(jdtls_root, system.get_config_suffix())
47+
local jdtls_root = resolver.get_jdtls_root(config)
48+
local jdtls_config = M.get_jdtls_config_path(jdtls_root)
4949

5050
local java_exe = 'java'
5151

5252
-- NOTE: eventhough we are setting the PATH env var, due to a bug, it's not
5353
-- working on Windows. So we are using the absolute path to java instead
5454
-- @see https://github.com/neovim/neovim/issues/36818
55-
if config.jdk.auto_install then
56-
local jdk_root = Manager:get_install_dir('openjdk', config.jdk.version)
57-
local java_home
58-
if system.get_os() == 'mac' then
59-
java_home = vim.fn.glob(path.join(jdk_root, 'jdk-*', 'Contents', 'Home'))
60-
else
61-
java_home = vim.fn.glob(path.join(jdk_root, 'jdk-*'))
62-
end
63-
55+
if config.jdk.auto_install or config.jdk.path then
56+
local java_home = resolver.get_jdk_home(config)
6457
java_exe = path.join(java_home, 'bin', 'java')
6558
end
6659

@@ -85,20 +78,37 @@ function M.get_jvm_args(config)
8578

8679
-- Adding lombok
8780
if use_lombok then
88-
local lombok_root = Manager:get_install_dir('lombok', config.lombok.version)
89-
local lombok_path = vim.fn.glob(path.join(lombok_root, 'lombok*.jar'))
90-
jvm_args:push('-javaagent:' .. lombok_path)
81+
jvm_args:push('-javaagent:' .. resolver.get_lombok_path(config))
9182
end
9283

9384
return jvm_args
9485
end
9586

87+
---@private
88+
---@param jdtls_root string
89+
---@return string
90+
function M.get_jdtls_config_path(jdtls_root)
91+
local config_path = path.join(jdtls_root, system.get_config_suffix())
92+
93+
if vim.fn.isdirectory(config_path) == 1 then
94+
return config_path
95+
end
96+
97+
local os_config_path = path.join(jdtls_root, 'config_' .. system.get_os())
98+
99+
if vim.fn.isdirectory(os_config_path) == 1 then
100+
return os_config_path
101+
end
102+
103+
err.throw(('nvim-java: jdtls config directory not found at %s or %s'):format(config_path, os_config_path))
104+
end
105+
96106
---@private
97107
---@param config java.Config
98108
---@param cwd? string
99109
---@return java-core.List
100110
function M.get_jar_args(config, cwd)
101-
local jdtls_root = Manager:get_install_dir('jdtls', config.jdtls.version)
111+
local jdtls_root = resolver.get_jdtls_root(config)
102112
cwd = cwd or vim.fn.getcwd()
103113

104114
local launcher_reg = path.join(jdtls_root, 'plugins', 'org.eclipse.equinox.launcher_*.jar')
@@ -115,7 +125,7 @@ function M.get_jar_args(config, cwd)
115125
equinox_launcher,
116126

117127
'-configuration',
118-
lsp_utils.get_jdtls_cache_conf_path(),
128+
lsp_utils.get_jdtls_cache_conf_path(jdtls_root),
119129

120130
'-data',
121131
lsp_utils.get_jdtls_cache_data_path(cwd),

‎lua/java-core/ls/servers/jdtls/env.lua‎

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
11
local path = require('java-core.utils.path')
2-
local Manager = require('pkgm.manager')
32
local log = require('java-core.utils.log2')
43
local system = require('java-core.utils.system')
4+
local resolver = require('pkgm.resolve')
55

66
local M = {}
77

88
--- @param config java.Config
99
function M.get_env(config)
10-
if not config.jdk.auto_install then
11-
log.debug('config.jdk.auto_install disabled, returning empty env')
10+
if not config.jdk.auto_install and not config.jdk.path then
11+
log.debug('config.jdk.auto_install disabled and config.jdk.path unset, returning empty env')
1212
return {}
1313
end
1414

15-
local jdk_root = Manager:get_install_dir('openjdk', config.jdk.version)
16-
17-
local java_home
18-
19-
if system.get_os() == 'mac' then
20-
java_home = vim.fn.glob(path.join(jdk_root, 'jdk-*', 'Contents', 'Home'))
21-
else
22-
java_home = vim.fn.glob(path.join(jdk_root, 'jdk-*'))
23-
end
15+
local java_home = resolver.get_jdk_home(config)
2416

2517
local java_bin = path.join(java_home, 'bin')
2618

‎lua/java-core/ls/servers/jdtls/plugins.lua‎

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
local M = {}
22

3-
function M.get_plugin_version_map(config)
3+
function M.get_plugin_config_map(config)
44
return {
5-
['java-test'] = config.java_test.version,
6-
['java-debug'] = config.java_debug_adapter.version,
7-
['spring-boot-tools'] = config.spring_boot_tools.version,
5+
['java-test'] = config.java_test,
6+
['java-debug'] = config.java_debug_adapter,
7+
['spring-boot-tools'] = config.spring_boot_tools,
88
}
99
end
1010

@@ -15,19 +15,18 @@ end
1515
function M.get_plugins(config, plugins)
1616
local file = require('java-core.utils.file')
1717
local List = require('java-core.utils.list')
18-
local Manager = require('pkgm.manager')
1918
local path = require('java-core.utils.path')
2019
local err = require('java-core.utils.errors')
2120
local str = require('java-core.utils.str')
21+
local resolver = require('pkgm.resolve')
2222

23-
local plugin_version_map = M.get_plugin_version_map(config)
23+
local plugin_config_map = M.get_plugin_config_map(config)
2424

2525
return List:new(plugins)
2626
:map(function(plugin_name)
27-
local version = plugin_version_map[plugin_name]
27+
local plugin_config = plugin_config_map[plugin_name]
2828

29-
local pkg_path = Manager:get_install_dir(plugin_name, version)
30-
local plugin_root = path.join(pkg_path, 'extension')
29+
local plugin_root = resolver.get_extension_root(plugin_name, plugin_config)
3130
local package_json_str = vim.fn.readfile(path.join(plugin_root, 'package.json'))
3231
local package_json = vim.json.decode(table.concat(package_json_str, '\n'))
3332
local java_extensions = package_json.contributes.javaExtensions

‎lua/java-core/utils/lsp.lua‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,23 @@ function M.get_jdtls_cache_root_path()
2323
return cache_root
2424
end
2525

26+
local function get_cache_key(value)
27+
if value == nil or value == '' then
28+
return nil
29+
end
30+
31+
return vim.fn.sha256(value)
32+
end
33+
2634
--- Returns the path to the jdtls config file
35+
---@param jdtls_root? string
2736
---@return string
28-
function M.get_jdtls_cache_conf_path()
37+
function M.get_jdtls_cache_conf_path(jdtls_root)
2938
local path = require('java-core.utils.path')
3039
local cache_root = M.get_jdtls_cache_root_path()
31-
local conf_path = path.join(cache_root, 'config')
40+
local cache_key = get_cache_key(jdtls_root)
41+
local conf_dir_name = cache_key and ('config_' .. cache_key) or 'config'
42+
local conf_path = path.join(cache_root, conf_dir_name)
3243
return conf_path
3344
end
3445

‎lua/java.lua‎

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,15 @@ function M.setup(custom_config)
2828
----------------------------------------------------------------------
2929
-- package installation --
3030
----------------------------------------------------------------------
31-
local Manager = require('pkgm.manager')
32-
local pkgm = Manager()
31+
local pkgm = require('pkgm.resolve')
3332

34-
pkgm:install('jdtls', config.jdtls.version)
33+
pkgm.install('jdtls', config.jdtls)
3534

3635
if config.java_test.enable then
3736
----------------------------------------------------------------------
3837
-- test --
3938
----------------------------------------------------------------------
40-
pkgm:install('java-test', config.java_test.version)
39+
pkgm.install('java-test', config.java_test)
4140

4241
M.test = {
4342
run_current_class = test_api.run_current_class,
@@ -54,7 +53,7 @@ function M.setup(custom_config)
5453
----------------------------------------------------------------------
5554
-- debugger --
5655
----------------------------------------------------------------------
57-
pkgm:install('java-debug', config.java_debug_adapter.version)
56+
pkgm.install('java-debug', config.java_debug_adapter)
5857
require('java-dap').setup()
5958

6059
M.dap = {
@@ -65,15 +64,15 @@ function M.setup(custom_config)
6564
end
6665

6766
if config.spring_boot_tools.enable then
68-
pkgm:install('spring-boot-tools', config.spring_boot_tools.version)
67+
pkgm.install('spring-boot-tools', config.spring_boot_tools)
6968
end
7069

7170
if config.lombok.enable then
72-
pkgm:install('lombok', config.lombok.version)
71+
pkgm.install('lombok', config.lombok)
7372
end
7473

7574
if config.jdk.auto_install then
76-
pkgm:install('openjdk', config.jdk.version)
75+
pkgm.install('openjdk', config.jdk)
7776
end
7877

7978
----------------------------------------------------------------------

0 commit comments

Comments
 (0)

Footer

© 2026 GitHub, Inc.