[BUG] Java LSP (JDTLS) Hover Operation Hangs on Complex Classes

Resolved 💬 7 comments Opened Jan 9, 2026 by jschenqiang Closed Feb 24, 2026

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 Claude Code built-in LSP tool hangs indefinitely when performing hover operations on Java classes with inheritance relationships (e.g., classes extending abstract classes or implementing interfaces), while the same operation works correctly on simple standalone classes.

What Should Happen?

claude should show right info when hover operations on Java classes with inheritance relationships (e.g., classes extending abstract classes or implementing interfaces) or show timeout

Error Messages/Logs

Steps to Reproduce

Environment

| Component | Version/Details |
|-----------|-----------------|
| Claude Code | 2.1.2 |
| Platform | Windows 10/11 (win32) |
| Java | OpenJDK 21.0.9 (Temurin-21.0.9+10-LTS) |
| Node.js | v22.19.0 |
| JDTLS Location | C:\Users\27555\AppData\Roaming\npm\jdtls.cmd |
| Date | 2026-01-09 |

Plugin Configuration

File: ~/.claude/settings.json

{
  "enabledPlugins": {
    "jdtls@claude-code-lsps": true,
    "vtsls@claude-code-lsps": true,
    "pyright@claude-code-lsps": true,
    "typescript-lsp@claude-plugins-official": true
  }
}

Project Structure

SimpleJavaDemo/
├── .classpath
├── .project
└── src/main/java/com/demo/
    ├── Calculator.java          # Simple class (no inheritance)
    ├── Person.java              # Simple class
    ├── Main.java
    ├── Application.java
    ├── model/
    │   ├── Printable.java       # Interface
    │   ├── Status.java          # Enum
    │   ├── AbstractEntity.java  # Abstract class implements Printable
    │   └── Employee.java        # Extends AbstractEntity
    ├── exception/
    │   ├── BusinessException.java
    │   ├── ValidationException.java
    │   └── NotFoundException.java
    ├── service/
    │   ├── Repository.java      # Generic interface
    │   ├── InMemoryRepository.java
    │   └── EmployeeService.java
    └── util/
        ├── StringUtils.java
        └── CollectionUtils.java

Total: 16 Java files

Steps to Reproduce

  1. Create a Java project with the structure above
  2. Ensure .classpath and .project files exist for Eclipse compatibility
  3. Enable jdtls@claude-code-lsps plugin in Claude Code settings
  4. Use Claude Code's LSP tool to perform operations

Test Commands

# This works (simple class)
LSP(operation: "hover", file: "Calculator.java", line: 4, char: 16)
# Result: "int com.demo.Calculator.add(int a, int b)"

# This hangs (class with inheritance)
LSP(operation: "hover", file: "Employee.java", line: 9, char: 40)
# Result: Hangs indefinitely (tested up to 5+ minutes)

LSP(operation: "hover", file: "AbstractEntity.java", line: 3, char: 20)
# Result: Hangs indefinitely

Expected Behavior

The hover operation should return type information for all Java classes, regardless of inheritance complexity, within a reasonable timeout (e.g., 10-30 seconds).

Actual Behavior

| File | Operation | Result | Time |
|------|-----------|--------|------|
| Calculator.java | hover | ✅ Success | <1s |
| Calculator.java | documentSymbol | ✅ Success | <1s |
| Calculator.java | findReferences | ✅ Success | <1s |
| Person.java | documentSymbol | ✅ Success | <1s |
| Person.java | hover | ❌ Hangs | >5min |
| Employee.java | documentSymbol | ✅ Success | <1s |
| Employee.java | hover | ❌ Hangs | >5min |
| AbstractEntity.java | documentSymbol | ✅ Success | <1s |
| AbstractEntity.java | hover | ❌ Hangs | >5min |

Pattern Observed

  • Works: Simple classes with no external dependencies (e.g., Calculator.java)
  • Fails: Classes with inheritance (extends), interface implementation (implements), or cross-package dependencies

Verification: JDTLS Works Independently

A Python script was created to test JDTLS directly via LSP protocol:

# test_lsp.py - Direct JDTLS communication test
# Results:
# - initialize: SUCCESS (2.46-3.16s)
# - textDocument/didOpen: SUCCESS
# - textDocument/hover: SUCCESS (receives response)

Test Results:

============================================================
Java LSP Hover Test
============================================================
Project: C:\project\SimpleJavaDemo
File: AbstractEntity.java
Timeout: 15s
------------------------------------------------------------
[OK] File loaded (1107 chars)
[OK] LSP process started
[OK] initialize done (2.46s)
[OK] initialized sent
[OK] File opened
[OK] hover response received (0.00s)
============================================================
Result: PASS
============================================================

This confirms that JDTLS itself is functioning correctly. The issue is specific to how Claude Code's LSP integration handles responses from JDTLS for complex classes.

Root Cause Analysis

| Hypothesis | Evidence |
|------------|----------|
| Response handling mismatch | JDTLS sends multiple JSON-RPC messages (notifications + response). Claude Code may not be correctly filtering/waiting for the actual hover response. |
| Async response timeout | Complex classes require more processing time. Claude Code may not have proper async handling for delayed responses. |
| Type resolution blocking | When resolving inheritance chains, JDTLS may need to index multiple files. This could cause blocking behavior in Claude Code's LSP client. |

Workaround

Currently, users can:

  1. Use documentSymbol operation (works for all files)
  2. Test simple classes with hover
  3. Use external Python script for direct JDTLS communication

Suggested Fix

  1. Add timeout handling for LSP hover requests with configurable timeout
  2. Improve response filtering to correctly identify hover responses vs. log messages
  3. Add async/non-blocking support for LSP operations on complex codebases
  4. Display progress indicator when LSP operations take longer than expected

Additional Files

  • test_lsp.py - Python script for direct JDTLS testing
  • .classpath - Eclipse classpath configuration
  • .project - Eclipse project configuration

Claude Model

None

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.2

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Terminal.app (macOS)

Additional Information

Claude encounters file path conversion issues when sending file paths to the LSP server on Windows, causing requests to fail after being sent.

Symptom: Internal error: Illegal character in authority at index 9: file://C:\...

Cause: Claude Code sends incorrect file URI format on Windows:

Incorrect: file://C:\project\DEMO

Correct: file:///C:/project/DEMO

Solution: Use a Node.js wrapper script to fix the URI. Refer to C:\Users\<USERNAME>\AppData\Roaming\npm\jdtls-wrapper.js

View original on GitHub ↗

This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗