Skip to content

[Bug] Windows 0.3.0 bundled JDTLS exits before initialization and hides the underlying error #177

Description

@1lck

Platform / 平台

Windows x64(具体 Windows 版本尚未收集)

Lithe version / Lithe 版本

尚未从故障机器的二进制中提取 source SHA,因此不能确认安装包与上述 HEAD 完全一致。

Environment / 环境信息

  • JDTLS:安装包内置 Eclipse JDT LS 1.38.0
  • 系统 JAVA_HOME:JDK 8
  • PATH 首个 Java:Zulu OpenJDK 21.0.11
  • Zulu 21 为解压安装,未注册到 JavaSoft
  • Lithe 安装于用户的 %LOCALAPPDATA% 下,实际路径和用户名已脱敏
  • 内置 jdtls.batjdtls.ps1config_win、Equinox launcher 和约 102 个插件 jar 均存在
  • 安装目录和 LSP 数据目录均可写,未发现只读属性、配置锁、端口占用或残留 JDTLS 进程

Steps to reproduce / 复现步骤

  1. 启动 Windows 安装版 Lithe 0.3.0。
  2. 打开一个 Java 项目。
  3. 打开 Java 文件。
  4. 等待约 3 秒,或 Ctrl+点击代码引用。
  5. 观察 LSP 状态和错误通知。

该问题在同一机器、同一项目中稳定复现。

Expected behavior / 预期行为

内置 JDTLS 使用可兼容的 JDK 17+ 启动并进入 ready,Java 补全、诊断和 Ctrl+点击跳转可用。失败时至少应在日志中保留 Core 的结构化错误、JDTLS stderr 和退出码。

Actual behavior / 实际行为

JDTLS 启动失败,UI 只显示:

Language server entered failed state

Java 语义功能和 Ctrl+点击跳转不可用。失败后没有存活的 Java/JDTLS 子进程。

Logs or diagnostic output / 日志或诊断输出

脱敏后的关键时间线:

11:52:46.635  workspace opened
11:52:57.846  syntax benchmark: language_id=java
11:53:01.016  LSP initialization error:
                Error: Language server entered failed state
                at lsp-client-ByNBX9Pn.js
                at startForFile
11:53:01.065  Failed to get git blame: Invalid Git blame request

从打开 Java 文件到失败约 3.17 秒,早于前端 waitUntilReady 的 12 秒超时,因此不是初始化超时。

JDTLS 数据目录 %LOCALAPPDATA%/app.lithe.windows/language-servers/jdtls/<workspace-hash>/ 已创建但始终为空,没有生成 .metadata/.log。这说明进程在 Eclipse/Equinox 创建 workspace metadata 前退出,无法从 JDTLS workspace log 取得原始异常。

A/B test / A/B 测试

已完全退出原 Lithe 进程,然后从临时设置以下环境的 PowerShell 启动新实例:

$env:JAVA_HOME = "C:\Program Files\Zulu\zulu-21"
& "<redacted>\lithe-windows.exe"

确认:

  • 只修改父 PowerShell 的进程级环境,没有修改注册表或系统环境;
  • 新 Lithe 是全新进程,不是复用旧实例;
  • 指定的 bin/java.exe 存在;
  • 打开相同项目和 Java 文件后仍然复现;
  • JDTLS 数据目录仍为空,没有存活的 Java 子进程。

因此现有证据不支持将“系统 JAVA_HOME 指向 JDK 8”认定为唯一根因。远程代码按 JAVA_HOME -> PATH -> well-known roots 发现 Java,过滤低于 17 的 runtime,并应通过 runtimeExecutablePath、进程级 JAVA_HOME--java-executable 将选中 JDK 传给启动器。代码中未发现 JavaSoft 注册表探测。

尚未完成的对照:在 Lithe 设置中显式填写 jdtlsJavaHomePath 后复现。

Confirmed findings / 已确认信息

  1. 内置 JDTLS、config_win 和插件文件存在且结构完整。
  2. LSP 数据目录在启动前成功创建,排除父目录创建/写权限错误。
  3. JDTLS 在约 3 秒内快速退出,未到达创建 .metadata 的阶段。
  4. 进程级 JAVA_HOME=Zulu 21 的 A/B 测试未改变结果。
  5. 当前日志无法提供实际 child process 命令行、进程环境、stderr 或退出码。
  6. Ollama token 错误和后续 git blame 错误与 JDTLS 启动失败无直接关系。

Diagnostic gap in current code / 当前诊断缺口

windows/tauri/src/platform/lsp-core-adapter.tswaitUntilReady 在收到 stateChanged: failed 后只抛出固定文案:

if (state === "failed" || state === "stopped") {
  throw new Error(`Language server entered ${state} state`);
}

但 Rust Core 的 stateChanged 事件已经携带 error,包括稳定错误码、stage、underlying detail 和可能的 exit code。adapter 没有将该错误用于 reject/log;log runtime events 也没有被转发到应用日志。因此原始 JDTLS stderr/退出原因在前端边界丢失。

Areas to investigate / 建议 Windows 端排查

  1. 在打包版 Windows 环境记录(脱敏后)实际启动的 executable、完整 arguments、child process 的 JAVA_HOMEruntimeExecutablePath、working directory、exit code 和 stderr。
  2. waitUntilReady 中保留并展示 stateChanged.error,同时将 Core log events 写入 Lithe 日志。
  3. 核对定制 jdtls.bat/jdtls.ps1 的参数转发,尤其是 --java-executable--jvm-arg-data-configuration 以及包含空格的路径。
  4. 对比上游 JDTLS wrapper 的 shared/cascaded configuration 参数。
  5. 在 Windows CI 对最终 NSIS 安装产物增加一次真实 JDTLS 启动 smoke test,至少等待 ready 并断言生成 workspace metadata。
  6. 确认故障安装包的实际 source SHA,排除前端资源和 Tauri/Rust host 来自不同构建版本。

Checklist / 提交前检查

  • 已搜索现有 issues;没有发现相同的未解决问题。
  • 已移除用户名、项目名、安装绝对路径及其他个人信息。
  • 本 issue 只陈述已验证事实;JDK 8/注册表信息未被当作已确认根因。

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingwindowssomething related to windows strongly

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions