[BUG] jdtls-lsp plugin: LSP tool fails with 'Command jdtls not found or is in an unsafe location' on Windows
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
The official jdtls-lsp plugin never successfully spawns jdtls on Windows 11, even after correctly installing Eclipse JDT.LS and adding a working wrapper script to PATH.
Every attempt to use LSP features (e.g., documentSymbol on .java files) fails with:
Error performing documentSymbol: Command 'jdtls' not found or is in an unsafe location (current directory)
This occurs consistently across:
- Multiple full app restarts
- Both
.batand.cmdwrapper variants - Two different PATH entries (top-level dir and bin subdir), confirmed present in persisted User PATH
- Direct terminal verification shows the wrapper script works perfectly when invoked directly
What Should Happen?
The LSP tool should spawn jdtls (found via PATH, resolved through the .bat wrapper) and successfully return document symbols for Java files.
Error Messages/Logs
Error performing documentSymbol: Command 'jdtls' not found or is in an unsafe location (current directory)
Steps to Reproduce
- Download Eclipse JDT Language Server release, extract to C:\jdt-language-server
- The release ships bin/jdtls (Python 3 script with shebang) + bin/jdtls.py, but NO Windows-native launcher
- Create a jdtls.bat wrapper on PATH:
@echo off
set "JAVA_HOME=C:\Program Files\Java\jdk-21.0.10"
python3 "%~dp0bin\jdtls" %*
- Verify from terminal that jdtls works correctly
- Install/enable the jdtls-lsp plugin, fully restart Claude Code
- Call the LSP tool (e.g., documentSymbol on a .java file)
Expected: LSP tool returns document symbols.
Actual: Command not found error appears.
Claude Model
Sonnet (default)
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
jdtls-lsp@claude-plugins-official v1.0.0
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
Suspected root cause:
The plugin's lspServers.jdtls.command is just the literal string jdtls (see marketplace.json), with no Windows-specific extension handling. On macOS/Linux, Eclipse JDT.LS ships bin/jdtls as an extension-less script with #!/usr/bin/env python3 shebang, directly executable. On Windows there is no equivalent — a bare extension-less filename is never directly executable; it requires .exe/.bat/.cmd.
The tool's command-resolution logic appears to either:
- Not attempt PATHEXT extension resolution (.bat/.cmd/.exe) at all, and/or
- Deliberately refuse to spawn resolved .bat/.cmd files as a security measure (the unsafe location wording suggests a deliberate block on shell-interpreted executables), with no documented Windows-compatible alternative.
Environment details:
- OS: Windows 11 Pro (10.0.26200)
- Claude Code CLI (via claude npm package)
- JDK 21.0.10 (required by jdtls release)
- Python 3.10 (required by jdtls.py-based launcher)
Suggested fixes:
- Ship a Windows-native jdtls.cmd/jdtls.exe launcher analogous to what other JDK tools do, OR
- Explicitly support/allow .bat/.cmd resolution via PATHEXT for this specific trusted, user-installed binary, OR
- Document a supported Windows installation path in the plugin README (currently only Homebrew/AUR instructions are provided — see plugins/jdtls-lsp/README.md, which has no Windows section)