fix(java): Run jdtls with a Lombok agent and show build errors at launch (#9)

* fix(java): Run jdtls with a Lombok agent and show build errors at launch

jdtls compiles with ECJ, which only generates Lombok members when the
server JVM runs -javaagent:lombok.jar. Nothing put it there, so @Data /
@Setter classes lost their accessors and Run launched stale classes
with "Unresolved compilation problem" stubs and no explanation.

- Projects whose build files mention Lombok get the newest jar: the
  IDE-managed one (new "Lombok (jdtls agent)" tool, latest release from
  Maven Central), else ~/.m2 (incl. settings.xml localRepository) or the
  Gradle cache. Each agent gets its own jdtls workspace so everything is
  rebuilt with it.
- Settings › Languages & Frameworks › Java › JVM options
  (java.jdt.ls.vmargs); a Lombok agent there wins.
- Run (and Debug, as a notification) list the first compile errors when
  the build has errors, plus a hint when Lombok is missing or older than
  1.18.34.

Fixes #3

* fix(java): Base the Lombok hint on the agent jdtls actually runs

A Lombok agent in Settings › Java › JVM options wins over the managed
and cached jars, but the launch hint still looked only at those: with
no cached jar it said Lombok was missing, and with an old cached one it
blamed that version although jdtls ran the user's. The hint and the
startup warning now use the user's agent (version from its file name).
This commit is contained in:
l0ng-ai authored and GitHub committed 2026-10-23 18:46:13 +08:00
1 parent 555ea8901f
commit acf6931017
24 files changed
+687 -19

No files matched your search

+15 -1
View File
@@ -6,7 +6,13 @@
*/
import { executeAction } from "@/platform/actions";
import { call, commands, IpcError, type LaunchConfig, type RunConfig } from "@/platform/ipc";
import { isJvmApplication, joinJavaArgs, parseJavaArgs, resolveJavaCommand } from "@/platform/javaLaunch";
import {
formatCompileErrors,
isJvmApplication,
joinJavaArgs,
parseJavaArgs,
resolveJavaCommand,
} from "@/platform/javaLaunch";
import { notifications } from "@/workbench/contributions";
export const JAVA_ADAPTER = "java-debug";
@@ -52,6 +58,14 @@ export async function javaLaunchConfig(rc: RunConfig, root: string): Promise<Lau
const parsed = parseJavaArgs(rc.args);
if (!parsed.mainClass) throw new Error(`No main class in '${rc.name}'`);
const info = await call(commands.javaResolveLaunch(module, parsed.classpath === "test", true));
if (info.errorCount > 0)
notifications().notify({
group: "run",
level: "warning",
key: "debug.java-compile-errors",
title: `'${rc.name}' has compile errors; debugging the last compiled classes`,
body: formatCompileErrors(info).trimEnd(),
});
const resolved = resolveJavaCommand(rc, info);
const port = await debugServer(module);
const classPaths = parsed.explicitClasspath ? parsed.explicitClasspath.split(/[:;]/) : info.classPaths;