github / github/copilot-cli

Java LSP : Hover definition works but definition doesn't

Abierto
#2,105 0 comentarios 1 reacción 0 asignados Ver en GitHub
area:tools
Lenguaje dominante
Shell
Estrellas
11.2k
Forks
1.9k
Merge medio
14 h 16 min
PR fusionados (30 d)
6

Descripción

### Describe the bug

`goToDefinition` via the LSP tool returns "No definition found" for **all types defined in Maven/Gradle dependency JARs** (e.g., Spring Framework, LangChain4j), even though `hover` at the exact same position correctly returns full type info and Javadoc from those same JARs.

### Root cause

During JDTLS initialization, the Copilot CLI does not send `extendedClientCapabilities.classFileContentsSupport: true` in `initializationOptions`. Without this flag, JDTLS will not return `jdt://` URIs in `textDocument/definition` responses for classes inside JARs — it returns null instead.

The relevant code in `app.js` constructs `initializationOptions` from `this.config.lspInitializationOptions`, but `lsp-config.json` has no such field, so it is `undefined`.

### Steps to reproduce

1. Configure JDTLS in `~/.copilot/lsp-config.json`:
```json
{
"lspServers": {
"java": {
"command": "jdtls",
"args": ["-data", "/tmp/jdtls-workspace"],
"fileExtensions": { ".java": "java" }
}
}
}
```
2. Open any Java project with Maven/Gradle dependencies
3. Run `hover` on a dependency type (e.g., `ChatModel` from LangChain4j, or `@Controller` from Spring):
```
> lsp hover ChatModel on line 43
✅ Returns: "dev.langchain4j.model.chat.ChatModel — Represents a language model..."
Source: langchain4j-core-1.11.0.jar
```
4. Run `goToDefinition` at the **exact same position**:
```
> lsp goToDefinition ChatModel on line 43
❌ Returns: "No definition found at line 43, character 25."
```

This affects all dependency types — Spring (`@Controller`, `@GetMapping`), LangChain4j (`ChatModel`, `UserMessage`), etc. Navigation to project-local classes works fine.

### Proposed fix

**1. Send `extendedClientCapabilities` during JDTLS initialization:**

Add `classFileContentsSupport: true` to the initialization options sent to JDTLS. This could be done via a new `lspInitializationOptions` field in `lsp-config.json`, or hardcoded for the Java/JDTLS server:

```json
{
"initializationOptions": {
"extendedClientCapabilities": {
"classFileContentsSupport": true
}
}
}
```

With this flag, JDTLS will return `LocationLink` objects with `jdt://contents/...` URIs for classes in JARs.

**2. Handle `jdt://` URIs in definition responses:**

When the LSP tool receives a definition result with a `jdt://` URI:
- Send a `java/classFileContents` request to JDTLS with that URI
- JDTLS responds with the decompiled (or source-attached) Java source code
- Display the source at the indicated range, similar to how VS Code shows read-only decompiled class files

### Additional context

The `getClientCapabilities()` method in `app.js` already declares `definition: { linkSupport: true }`, so the LSP protocol side is correct. The only missing piece is the JDTLS-specific `extendedClientCapabilities`.

This would also benefit `goToImplementation` for interfaces defined in JARs, and `findReferences` completeness for dependency types.

Related: #1349 (broader Java/JVM ecosystem awareness)

### Additional context

### Environment

- **Copilot CLI**: 1.0.6
- **JDTLS**: 1.57.0 (via Homebrew)
- **OS**: macOS (Apple Silicon)
- **Java project**: Spring Boot with Maven dependencies

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.