Spring Boot Runner (plugin-free) — VSCode ExtensionA VSCode extension that runs an unpackaged Spring Boot (Maven) project straight from the
command line via It is a thin UI over
The runner is pure Node (ESM), so no Python install is required — only a Maven on PATH and a JDK. Source repository(源码仓库)Gitee:
WhyThe Spring Boot Dashboard "runs" an app by resolving the Commands| Command | What it does |
| --- | --- |
| Run/debug configurations —
|
| Field | Default | Meaning |
|---|---|---|
module |
"" |
Maven module directory name (empty = auto-detect). |
mainClass |
"" |
Fully-qualified main class (empty = auto-detect from @SpringBootApplication). |
programArgs |
"" |
Program arguments, space-separated (quote values containing spaces). |
vmArgs |
"" |
Extra JVM arguments, space-separated. |
profiles |
"" |
spring.profiles.active. |
port |
"" |
Override server.port. |
workingDir |
"" |
Working directory of the java process (empty = the module directory). |
env |
"" |
Extra KEY=VALUE env vars, semicolon-separated. |
envFile |
"" |
Path to a .env file to load. |
javaHome |
"" |
JDK home for both the Maven build and the launched app (empty = java on PATH). |
debugPort |
"5005" |
JDWP port used when debugging. |
suspend |
true |
When debugging, suspend the JVM until the debugger attaches. |
jrebel |
false |
Auto-detect the locally installed JRebel extension and inject -agentpath:…/jrebel64.dll. |
force |
false |
Rebuild even when nothing changed (ignore the build cache). |
clean |
false |
Run mvn clean before building. |
skipTests |
true |
Skip tests during the build. |
offline |
false |
Maven offline mode (-o). |
JRebel (hot reload) without hard-coding a path
Tick 自动检测 JRebel in the panel (or write "jrebel": true in launch.json) and the
extension finds the native agent at run time and appends -agentpath:<abs path> to the JVM
arguments. This replaces hand-writing
-agentpath:C:\\Users\\me\\.vscode\\extensions\\jrebelbyperforcesoftware.jrebel-2026.3.2\\agent\\jrebel\\lib\\jrebel64.dll
which silently breaks the moment JRebel updates and the version number in the directory name
changes (the JVM then refuses to start with Invalid -agentpath argument).
Search order, first hit wins:
springBootRunner.jrebelAgentPathsetting — explicit override.vscode.extensions.all— the host's own list, so the realextensionPathis used.- The host's
extensions.jsonmanifest — authoritativeidentifier.id+version+ location, and it works even when JRebel is installed but disabled in this window. - Directory-name scan of the extension folders — last-resort fallback.
Sources 2 and 3 carry a version, so when several JRebel builds are installed the newest wins.
The scan never assumes a directory-name shape: the same JRebel is
jrebelbyperforcesoftware.jrebel-2026.3.2 in .vscode but
jrebelbyperforcesoftware.jrebel-2026.3.2-universal in CodeBuddy.
Notes:
- The file picked matches the current platform and CPU arch (
jrebel64.dll/libjrebel64.so/libjrebelaarch64.so/libjrebel64.dylib); loading the wrong one makes the JVM fail with a bad-ELF / cannot-load error. - If your
vmArgsalready contain-agentpath:…jrebel…or-Drebel.home=…, injection is skipped — loading the same native agent twice aborts the JVM. You are told this happened. rebel.xmlis still generated by JRebel's own wizard; this only mounts the agent.- When the run configuration is started and nothing was found, you get a warning with a 设置 agent 路径 action rather than a silent no-op.
Running / stopped state in the panel
A configuration that is currently running shows a green ● before its name and replaces the
▶ / 🐞 pair with a red stop button (■), always visible without hovering. Clicking it kills
only that configuration's process tree — other configurations keep running.
The state comes from the per-configuration PID file the runner writes
(%TEMP%/spring-boot-runner-<project>-<config>.pid) combined with a liveness check, so the
indicator clears itself when the app exits on its own or is killed externally. It is polled every
2 s because process death, unlike a debug session, emits no event we can subscribe to.
request: "attach" fields: hostName (default localhost), port (default 5005), timeout.
An attach configuration neither builds nor starts anything — only the debugger is attached, and no
extra session is created for this extension.
All string fields accept the usual launch.json variables — ${workspaceFolder},
${workspaceFolderBasename}, ${userHome}, ${env:NAME} — both when started via F5 (VSCode
substitutes them) and when started from the Run/Debug Configurations panel (the extension
substitutes them itself).
The file is edited through jsonc edits, so entries of other debuggers (java, node, chrome,
…) and any comments you wrote are preserved. Entries whose type is not spring-boot-runner are
never touched, and a launch.json that does not parse is reported instead of being overwritten.
Earlier versions stored configurations in
.vscode/spring-boot-runner.jsonand read flatspringBootRunner.*settings. Both are no longer read or written —.vscode/launch.jsonis the single source of truth.
javaHome (JDK selection)
javaHome resolves java as <javaHome>/bin/java and exports JAVA_HOME=<javaHome> (plus
<javaHome>/bin first on PATH) for every Maven invocation, so mvn install compiles with the same
JDK that launches the app — mvn.cmd picks its java via JAVA_HOME. Useful when the integrated
terminal's java is the wrong version (e.g. the project needs JDK 21 but PATH has JDK 17).
Three ways to set it:
- Panel —
Run/Debug Configurations…→ theJDK (JAVA_HOME, 留空用 PATH 上的 java)field. - Command —
Spring Boot Runner: Configure Java Home…prompts for the path and stores it in a chosen run configuration. - launch.json — write
"javaHome": "C:\\Program Files\\Java\\jdk-21"directly.
Activity Bar entry
The extension contributes an Activity Bar container (leaf+play icon, media/activity-icon.svg)
named Spring Boot Runner. Clicking it opens a view with one-click links for
Run / Debug / Custom Args / Stop.
Note: VSCode renders Activity Bar icons monochrome (theme foreground color) — the colored
images/icon.png only shows in the Extensions panel, never in the Activity Bar. The top-level
icon field and the Activity Bar icon are two independent mechanisms.
Settings
Only three installation-level settings remain; everything that describes a run lives in
launch.json. Set via the Settings UI or .vscode/settings.json:
| Key | Default | Meaning |
|---|---|---|
springBootRunner.nodePath |
"" |
Node.js interpreter for run-spring-boot.mjs (empty = node on PATH). Set an absolute path only if node is not resolvable from the integrated terminal. |
springBootRunner.runnerScript |
null |
Path to run-spring-boot.mjs (defaults to the bundled copy under scripts/). |
springBootRunner.jrebelAgentPath |
"" |
Override for the JRebel native agent path. Leave empty — auto-detection covers the normal cases; use this only when JRebel lives somewhere the search cannot reach. Supports ${userHome}. |
How Stop works
On start, run-spring-boot.mjs writes its PID to
%TEMP%/spring-boot-runner-<project>[-<config name>].pid — the configuration-name suffix keeps
several run configurations of one project from overwriting each other's PID and @argfile.
Stop reads those files and kills the whole process tree (node → cmd.exe → java) with
taskkill /PID <pid> /T /F (Windows) / kill -9 <pid> (others). The PID file is removed on exit.
The same cleanup runs when you press the Stop button of a spring-boot-runner debug session,
so F5-started apps are stopped from the debug toolbar too.
Build & install (run these yourself)
cd spring-boot-runner-vscode
npm install # also installs jsonc-parser (used to edit launch.json safely)
npm run compile # emits dist/extension.js
# To produce a .vsix you can install in VSCode:
npx @vscode/vsce package # needs @vscode/vsce; installs on demand
Then in VSCode: Extensions → … → Install from VSIX…, pick the generated .vsix.
For local dev, press F5 in this folder to launch an Extension Development Host.