Buy @ Amazon

Pro-Grade Java Development in Claude Code - Beyond Grep with LSP


In the world of AI driven coding, context is currency. Most developers run Claude Code (CC) in its "out-of-the-box" state, relying on the agent's internal grep tool to navigate codebases. While Claude is brilliant, grep is a blunt instrument.

To transform CC into a true "Senior Pair Programmer," you need to bridge the gap between Pattern Matching and Semantic Understanding. This is where the Language Server Protocol (LSP) and Eclipse JDT.LS come in.


🧠 Why the "LLM is Smart Enough" Argument Fails

A common misconception is that the LLM's reasoning capabilities negate the need for local tooling. This is incorrect for two critical reasons:

  1. The Noise Tax: When you ask CC to "find all usages of a method," grep returns every string match, including Javadocs, logs, and commented-out code. This "noise" is sent to the LLM, consuming thousands of unnecessary tokens and increasing the risk of the model losing the "signal" in the mess.
  2. The Latency Gap: A keyword search followed by LLM filtering takes 10–60 seconds. An LSP query (like textDocument/references) returns the exact AST (Abstract Syntax Tree) coordinates in milliseconds.

The Semantic Advantage

While grep sees text, Eclipse JDT LS sees structure. It understands the difference between a method call, a variable declaration, and a string literal—allowing CC to operate with surgical precision.


🎓 The Expert Setup: CC + DevContainers

For a reproducible high-performance environment, you should manage your LSP via a DevContainer. (And if you have been following me from my earlier blogs, you would know that I am an advocate of running CC in isolated environments for security reasons, and I love and leverage Docker for this.) This ensures that jdtls and its dependencies (JDK 17/21) are isolated from your host machine.

1. Setting up Java LSP for CC in DevContainer

  • The Dockerfile: Minimal reference implementation:
    ----
  • Also, do feel free to check out my reference implementation in the DhanHQ-java repository for the exact docker-compose and settings.json configurations.

2. The Environment Variable

As of April 2026, the LSP tool is enabled via an undocumented feature flag (It was discovered via GitHub Issue #15619 and that issue still is in Open status). This is the "secret sauce" for power users.

  • Flag: ENABLE_LSP_TOOL=1 
  • Ensure that in your `.claude/settings.json` its `env` attributes is set with `"ENABLE_LSP_TOOL": "1"`.
  • I personally have `export ENABLE_LSP_TOOL=1` done to my shell profile via my Dockerfile/docker-compose.yaml file for my CC-Dev-Container.

3. Installing LSP Plugin in CC

Post Java LSP installation and CC configuration set-up in its `settings.json`, start CC and run command `/plugins` to install jdtls-lsp from Claude's Plugins Official marketplace and then do run `/reload-plugins` for the installed plugin to kick-in.

🔬Testing and Trouble-shooting

If you have an `OrderEndpoint.java` class in your java project, run a prompt like one of the below:
    • Find all references to OrderEndpoint
    • Get me the definition of OrderEndpoint
    • List all functions in OrderEndpoint
    • Find the OrderEndpoint class in the project
    • Where is placeOrder defined
All of the above should hit LSP and respond quickly in milliseconds. If it is taking time, it is likely that it is using `grep` functionality to do keyword search and send the result to your LLM with lot of noise including matches in imports and comments taking anywhere between 10-60 seconds and burning a lot of your tokens.

Known Constraints & Troubleshooting

  • Plugin Reloading: Always run `/reload-plugins` after installing the jdtls-lsp plugin from the official-marketplace to ensure the bridge is established.
  • Memory Overhead: jdt.ls is a headless Eclipse instance. Ensure your container has at least 4GB of RAM. Insufficient memory will cause the LSP to crash, and CC will silently fall back to grep.
  • Index Warm-up: On massive projects, give the LSP 30-60 seconds to index the classpath before expecting instant results.

⚡ Performance Benchmark: LSP vs. Grep

When testing your setup, look for these "Expert-Level" behaviors:
Prompt Without LSP (Grep) With LSP (jdt.ls)
Find definition of processOrder   Scans whole project; may pick wrong file Jumps directly to source line 
 List class methods in  MyConnection Returns method names + Javadoc noise  Returns a clean, structured symbol list 
 Find references of OrderEndpoint Returns string matches (Slow/Expensive)  Returns actual code usages (Fast/Cheap) 

By integrating Java LSP, you aren't just adding a tool; you are upgrading Claude's "vision." You save money on tokens, reduce latency, and allow the LLM to focus on logic rather than data filtering.