> ## Documentation Index
> Fetch the complete documentation index at: https://openidea.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Java 与 Kotlin

> OpenIDEA 如何借助 JDT LS、Kotlin LSP、Maven 和 Gradle 为 Java 与 Kotlin 项目提供代码智能、构建、运行、测试和调试。

Java 的代码智能由 Eclipse JDT Language Server（jdtls）提供，OpenIDEA 还为它加载了一组随应用发布的扩展 bundle；Kotlin 使用 JetBrains 的 Kotlin LSP。Maven 和 Gradle 项目会自动导入，两种语言的运行、测试和调试都走同一套运行配置。与其他语言的对比见[语言支持总览](https://openidea.sh/zh/languages/index.md)。

## 语言服务器

| 语言 | 服务器 | 备选 | 调试器 |
| - | - | - | - |
| Java | Eclipse JDT Language Server（`jdtls`） | `kmp-lsp` | Microsoft java-debug，加载在 jdtls 内 |
| Kotlin | Kotlin LSP（JetBrains，`kotlin-lsp`） | Kotlin Language Server（fwcd，`kotlin-language-server`） | Kotlin Debug Adapter（fwcd） |
| Groovy、Gradle 脚本 | `groovy-language-server`（需自行提供） | | |
| JSP | 无（仅语法高亮） | | |

备选服务器只在排在它前面的服务器未安装时才会启动。想手动指定，打开 **设置 › 语言和框架 › 语言服务器**，选中其中一个服务器，在 **Java 语言服务器**（或 Kotlin 语言服务器）里选择：**自动** 使用第一个可用的，**无** 关闭代码智能。这个选择可以全局生效，也可以只对当前项目生效。

`kmp-lsp` 不运行 JVM，提供基于语法的 Java 代码智能，没有 JDT 的编译分析、Lombok 支持和 JDT 的重构。构建和运行 Java “应用程序”配置、类路径发现以及 Java 调试器都需要 jdtls。

### 随 IDE 提供的部分

在原版 jdtls 之上，OpenIDEA 会加载仓库 [`java/`](https://github.com/l0ng-ai/openidea/tree/main/java) 目录里的扩展 bundle：

* **java-usages**：查找用法能区分读和写；对字段，还会一并找出它的 getter、setter 和 builder（包括 Lombok 生成的）。查找用法默认只搜项目源码（**项目文件**），选择 **项目和库** 时才会搜索依赖 jar。
* **Spring 配置导航**：见 [Spring](#spring)。
* **kotlin-bridge**：在 Java 与 Kotlin 混合的 Maven 项目里，让 Java 代码能看到 Kotlin 类。见下文“Maven 项目中的 Kotlin”。
* **Lombok**：应用内置一个打过补丁的 Lombok agent（1.18.48，修复了在当前 JDT LS 上的问题），无需下载。

没有源码的库类会以反编译后的 `jdt://` 文档打开。依赖有源码包时，jdtls 会下载 Maven 和 Eclipse 源码。

## 环境配置

### 安装服务器

打开 Java 或 Kotlin 文件时，如果对应的服务器缺失，会弹出通知并提供 **安装** 按钮。也可以在 **设置 › 语言和框架 › 语言服务器** 里安装、重新安装或卸载每个工具。所有工具都装进 IDE 自己的工具目录，不需要管理员权限：

| 工具 | 来源 |
| - | - |
| Eclipse JDT Language Server | download.eclipse.org 上的最新 milestone |
| Java 调试器（Microsoft java-debug） | Open VSX 上的 `vscjava.vscode-java-debug` 扩展 |
| Lombok（jdtls agent） | 随应用内置 |
| Kotlin LSP（JetBrains） | `Kotlin/kotlin-lsp` 的 GitHub release |
| Kotlin Language Server（fwcd） | `fwcd/kotlin-language-server` 的 GitHub release，需要 Java |
| Kotlin Debug Adapter | `fwcd/kotlin-debug-adapter` 的 GitHub release，需要 Java |
| kmp-lsp | `Hessesian/kmp-lsp` 的 GitHub release |

`PATH` 上已有的 `jdtls`（Homebrew、Scoop 或 release 压缩包）也能直接用。OpenIDEA 直接在 JVM 上启动它，不经过它自带的 Python 启动脚本，所以不需要装 Python。没装 java-debug 就开始调试时，IDE 会提示安装，并带着这个 bundle 重启 jdtls。

Groovy 没有安装程序：需要自行构建 [groovy-language-server](https://github.com/GroovyLanguageServer/groovy-language-server)，以 `groovy-language-server` 的名字放到 `PATH` 上，或在 **语言服务器** 页面里指定可执行文件。

### JDK 检测

OpenIDEA 会在这些位置查找已安装的 JDK：`JAVA_HOME`、`PATH` 上的 `java`、`/Library/Java/JavaVirtualMachines`（系统级和用户级）、`/usr/lib/jvm`、Homebrew、SDKMAN、mise、asdf、`~/.jdks`，以及 Windows 上 `Program Files` 下常见的厂商目录。IDE 自己下载的 JDK 也会被找到。JDK 列表旁的 **重新检测** 可以重新扫描。

**设置 › 语言和框架 › Java** 里有两项 JDK 设置：

* **项目 JDK › SDK**：用于编译和运行项目。它是 jdtls 的默认运行时、运行/调试使用的 JDK，也是 Maven 和 Gradle 的 `JAVA_HOME`。选 **自动** 时，每个模块使用与其目标 Java 版本匹配的已安装 JDK。
* **语言服务器 › JDK**：只用来运行 jdtls，因此 Java 8 或 17 的项目也能用上新版 jdtls。选 **自动** 时，项目 JDK 版本够新就用它，否则用第一个满足要求的已安装 JDK；一个都没有时，会自动下载 Eclipse Temurin 到单独的语言服务器运行时目录。

jdtls 需要 JDK 21 或更高版本，部分 jdtls 版本要求更高，OpenIDEA 会从已安装的 jdtls 中读取实际要求。检测到的每个 JDK 还会作为运行时（`JavaSE-17`、`JavaSE-21`……）注册给 jdtls，所以目标是 Java 17 的模块会针对 JDK 17 编译，而不是针对运行 jdtls 的那个 JDK。

**语言级别** 在构建文件没有指定时决定 Java 源码和字节码级别。每个 JDK 列表里都有 **下载 JDK…**，可以选择版本，把 Eclipse Temurin 下载到 IDE 的 JDK 目录。当 jdtls、某个运行配置或 Maven/Gradle 同步找不到足够新的 JDK 时，也会提示同样的下载。

Kotlin Language Server（fwcd）最高只能在 Java 21 上运行。如果 `JAVA_HOME` 指向更新的 JDK，IDE 会改用已安装 JDK 中符合要求的最新版本来启动它。

### 内存与 JVM 选项

每个项目窗口各自启动一个 jdtls，有独立的工作区和索引。jdtls 默认使用以下 JVM 选项：

```text theme={null}
-XX:+UseG1GC -XX:G1PeriodicGCInterval=60000 -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=30 -Xmx2G -Xms100m
```

G1 加上周期性回收，可以在导入或构建结束后把内存还给系统。要调整上限，在 **设置 › 语言和框架 › Java › 语言服务器 › JVM 选项** 中填写，例如 `-Xmx1g` 或 `-Xmx4g`。你设置的选项会替换同一项的默认值；指定其他回收器（如 `-XX:+UseZGC`）时，默认的回收器相关选项会全部去掉。该设置可以全局配置，也可以按项目配置。

**在构建间共享 JDT LS** 让一个本地项目窗口里所有关联的构建共用一个 jdtls，而不是每个构建一个。不同项目窗口之间仍然是各自独立的进程。

jdtls 的工作区保存在 IDE 的数据目录（`lsp/jdtls/`）中，不在项目里；jdtls 也不会往项目里写 `.project`、`.classpath` 或 `.settings`。见[数据目录与日志](https://openidea.sh/zh/reference/data-directories.md)。

### Lombok

项目用到 Lombok 时（在构建文件、继承的父 POM 或 Gradle 构建中声明，或源码里有相关 import），OpenIDEA 会给 jdtls 加上 Lombok agent。默认使用 **语言服务器** 页面里的那个，也就是内置的版本；没有时会退回到 Maven 或 Gradle 缓存里最新的 Lombok。你在 **JVM 选项** 里自己写的 `-javaagent` 优先。项目自身的 Lombok 依赖不会被改动。

## 构建工具

jdtls 会自动导入 Maven 和 Gradle 项目（包括 Gradle wrapper）。没有构建文件的目录会作为普通 Java 项目打开，`lib/` 下的 jar 会加入类路径。OpenIDEA 还提供 **Maven** 和 **Gradle** 工具窗口，用来执行目标和任务、重新加载、切换 profile 以及分析依赖。相关设置在 **设置 › 构建、执行、部署 › Maven** 和 **Gradle**：

* Maven：**JRE**、**Maven 主路径**（默认用项目的 `mvnw`，没有则用 `PATH` 上的 `mvn`）、**用户设置文件**、**Toolchains 文件**、**本地仓库**、**活动 profiles**、**线程数** 和 **使用 Maven Daemon (mvnd)**。在 Maven 工具窗口里选的 profile 也会传给 jdtls，编辑器看到的依赖与该 profile 一致。
* Gradle：**构建和运行使用**（Gradle 或 OpenIDEA）、**Gradle 使用的 JVM**、**分发**（Gradle 包装器或本地安装）、**Gradle 主路径** 和 **Gradle 用户主目录**。

IDE 会把代理设置传给 jdtls，所以在代理环境下也能解析依赖。工具窗口的用法见[构建工具](https://openidea.sh/zh/guide/build-tools.md)。

### Maven 项目中的 Kotlin

在含 Kotlin 源码的 Maven 项目里，每次保存后 OpenIDEA 会在后台用项目自己的 Maven 配置构建 Kotlin 代码，输出到一个私有目录，再把编译好的 Kotlin 类作为库交给 jdtls。这样同一模块或其他模块的 Java 代码就能调用 Kotlin 代码。这次构建的错误会以 `kotlin-bridge` 的名义出现在 **问题** 中；在下一次构建成功之前，继续使用上一次成功的结果。这个桥接只覆盖编译后的 Kotlin API，从 Java 跳转到 Kotlin 源码、分析未保存的 Kotlin 修改以及跨语言重构都不在其中。

## 运行与测试

| 对象 | 运行方式 |
| - | - |
| `main` 方法 | **应用程序** 配置，使用模块的运行时或测试类路径；支持 Java 25 的实例 `main` 方法 |
| `@SpringBootApplication` 类 | **Spring Boot** 配置，可设置活动 profile 和更新操作 |
| 可执行 jar | **JAR 应用程序** 配置 |
| WAR | **Tomcat 服务器** 配置，运行在本地 Tomcat 安装上（IDE 不会往安装目录里写东西） |
| JUnit 4、JUnit 5、TestNG 测试 | Maven（Surefire `-Dtest=…`）或 Gradle（`--tests …`）测试配置 |

main 方法、测试类和测试方法旁的边栏图标会创建这些配置；Maven 和 Gradle 的运行配置会从构建文件中自动检测。对 Gradle 项目，**构建和运行使用** 决定“应用程序”是作为 Gradle 的 `JavaExec` 任务运行（默认），还是由 OpenIDEA 用 jdtls 给出的类路径直接启动。

测试结果从 Maven 和 Gradle 生成的 JUnit XML 报告中读取，通过的测试也会列出；测试树支持只重跑失败的测试。Gradle 运行配置的 VM 选项会作用到 Gradle fork 出来的 JVM（`run`、`bootRun`、`test`）。类路径超出命令行长度限制时（Windows 上常见），会改用参数文件或只含 manifest 的 jar。

另见[运行配置](https://openidea.sh/zh/guide/run.md)和[测试](https://openidea.sh/zh/guide/testing.md)。

## 调试

Java 调试使用 jdtls 内的 Microsoft java-debug，Kotlin 调试使用 Kotlin Debug Adapter。可以调试：

* “应用程序”、Spring Boot、“JAR 应用程序”和“Tomcat 服务器”配置。
* 会启动 JVM 的 Maven 和 Gradle 配置（测试、`spring-boot:run`、`bootRun`、`run`）：IDE 会加上 JDWP agent，等 JVM 就绪后自动附加，输出和测试树仍留在运行工具窗口里。
* 在别处启动的进程：使用 **远程 JVM 调试** 配置。

**运行 › 调试操作 › 重新加载已更改的类**（HotSwap）会编译你的修改并加载到正在运行的会话中。Spring Boot 和 Tomcat 配置还支持 **运行 › 更新应用**（`⌘F10` / `Ctrl+F10`），行为由 **执行“更新”操作时** 选项决定。

另见[调试](https://openidea.sh/zh/guide/debugging.md)。

## 框架支持

### Spring

* **Spring Boot 运行配置**：根据 `@SpringBootApplication` 类创建，默认显示在 **服务** 工具窗口中。
* **配置导航**：在 `application.yml` 或 `.properties` 的键上转到定义，会打开绑定到它的 Java 成员（`@ConfigurationProperties`、`@Value`、`Environment.getProperty`）；反过来，从 Java、YAML、properties 或 Spring XML 里的 `${…}` 占位符也能跳到配置键。依赖中 `spring-configuration-metadata.json` 描述的键会跳到对应的源类。对配置键执行 **查找用法**，会同时列出配置声明和 Java 中的使用处。
* **Spring Web 端点**：Java 和 Kotlin 控制器中的请求映射旁有边栏图标，还有 **在 HTTP 客户端中生成请求** 和 **为控制器生成请求** 两个操作，会把请求写进一个临时 `.http` 文件。随处搜索的 **全部** 标签页可以按请求路径搜索。见 [HTTP Client](https://openidea.sh/zh/guide/http-client.md)。
* **Facet**：在 **项目结构**（`⌘;` / `Ctrl+Alt+Shift+S`）里记录模块使用的框架（Web、Spring、JPA）。添加 Web Facet 还会把其中的 `WEB-INF/lib/*.jar` 加入 jdtls 的类路径。

### MyBatis

MyBatis mapper 接口与 XML 语句之间的跳转由 MyBatis Navigator 插件（[`plugins/official/mybatis`](https://github.com/l0ng-ai/openidea/tree/main/plugins/official/mybatis)）提供，不属于 IDE 本体。

## 已知限制

* 每个项目窗口运行一个 jdtls，同时打开多个大项目时内存会叠加。可以在 **JVM 选项** 中调低 `-Xmx`，或关闭暂时不用的窗口。**在构建间共享 JDT LS** 只在单个窗口内有效。
* 没有 jdtls 时（例如只用 `kmp-lsp`），“应用程序”配置、依赖类路径的功能和 Java 调试都不可用。
* Java 测试通过 Maven 或 Gradle 运行，两者都没有的项目没有测试运行器。
* Kotlin 桥接只支持 Maven，只把编译后的 Kotlin 类暴露给 Java，不提供从 Java 到 Kotlin 源码的跳转或重构。
* Groovy 需要自行构建 `groovy-language-server`，JSP 只有语法高亮。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.