Local Tomcat Launcher在 VSCode 中一键启动 / 停止 / 重启 / 刷新本机 Tomcat,内置 Tomcat 9,支持 JPDA 远程调试、Maven 构建与文件级热加载。 功能特性
建议开启
|
| 条件 | 说明 |
|---|---|
| VSCode | >= 1.85.0 |
| redhat.java | 扩展依赖(自动安装),提供 JDK 识别与自动构建(autobuild)能力 |
| 操作系统 | 仅支持 Windows |
| 项目类型 | 单模块 Maven Web 项目(含 pom.xml,标准目录布局 src/main/java、src/main/resources、src/main/webapp) |
| Maven | 已安装,命令行可访问 mvn |
| JDK | 已安装,并被 redhat.java 识别 |
快速开始
- 在 VSCode 中打开一个 Maven Web 项目(包含
pom.xml)。 - 编辑器右上角出现四个紧密排列的按钮:启动(▶)、停止(■)、重启(↻)、刷新(⟳)。
- 首次使用前,请确保项目已构建(即
target/{finalName}目录存在)。可点击 刷新 按钮,它会自动执行mvn package后再启动;或自行在终端执行mvn package。 - 点击 启动,输出通道立即弹出,等待部署完成(状态栏变为「运行中」)。
- 浏览器访问
http://localhost:{port}/{contextPath}查看项目,例如http://localhost:8080/dev。 - 修改
src/main/java、src/main/resources、src/main/webapp下的文件并保存后,变更会自动热加载(无需重启)。
配置项
在 VSCode 设置中搜索 support.tomcat:
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
support.tomcat.home |
string | "" |
Tomcat 安装路径。留空则使用插件内置的 resources/tomcat9 |
support.tomcat.port |
number | 8080 |
HTTP 发布端口 |
support.tomcat.debugPort |
number | 5005 |
Debug 端口(JPDA / JDWP) |
support.tomcat.contextPath |
string | "dev" |
部署名称 / 上下文路径 |
support.tomcat.vmOptions |
string | "" |
Tomcat 启动时的 VM 参数(注入到 CATALINA_OPTS) |
所有配置项为工作区级别(
scope: workspace),修改后立即对下一次启动生效。
使用指南
启动(Start)
点击启动按钮时,插件会依次执行:
- 防连点保护与状态检查(运行中 / 启动中则提示并返回)。
- 端口检测:检查 HTTP 端口与 Debug 端口是否被占用,占用则报错并返回。
- 准备 CATALINA_BASE:在插件存储目录(
storageUri/tomcat)下重建隔离目录(conf、logs、temp、work、lib),并复制内置 / 外部 Tomcat 的conf配置。 - 复制
startup-signal-listener.jar到CATALINA_BASE/lib(供server.xml的<Listener>加载)。 - 修改
server.xml:替换 HTTP 连接器端口与shutdown端口(设为-1),注入StartupSignalListener(signalDir指向信号目录)。 - 修改
logging.properties:让localhost日志同时输出到控制台。 - 写入部署描述符
conf/Catalina/localhost/{contextPath}.xml,docBase指向target/{finalName}(该finalName通过mvn help:evaluate取得),reloadable="false"。 - 注入环境变量(合并进程环境后启动):
CATALINA_HOME— Tomcat 安装目录CATALINA_BASE— 隔离实例目录JPDA_ADDRESS/JPDA_TRANSPORT— Debug 端口与dt_socketJRE_HOME— 自动识别的 JDK 路径(见下文「JDK 版本」)CATALINA_OPTS— 用户配置的 VM 参数(仅 start / run 生效,stop 不使用)
- 通过 PowerShell 调用
catalina.bat jpda run启动,日志实时输出到通道。
启动成功判定:通过信号文件机制判定,不依赖日志文本匹配。StartupSignalListener 在 Tomcat Server AFTER_START 事件时遍历所有 webapp context:
- 全部 context 状态为
STARTED→ 写success.tomcat(权威成功信号) - 存在 context 非
STARTED(FAILED / STOPPED 等)→ 写fail.tomcat(含失败 context 列表),扩展收到后杀掉半启动的 Tomcat 进程并报错
VSCode 扩展通过 FileSystemWatcher 监听信号目录(storageUri/signal/*.tomcat),收到 success.tomcat 判定成功,收到 fail.tomcat 判定失败。默认超时 300 秒,超时则判定失败并清理进程。
注意:启动流程不会自动执行 Maven 构建。请确保在启动前
target/{finalName}已存在(使用「刷新」按钮或先mvn package)。
JDK 版本
Tomcat 启动时自动使用 redhat.java 扩展识别的 JDK,查找优先级:
java.configuration.runtimes中default: true的路径java.configuration.runtimes中第一个有path的运行时java.jdt.ls.java.home- 系统环境变量
JAVA_HOME - 系统环境变量
JRE_HOME
若均不可用,输出警告并回退到系统默认 JRE_HOME / JAVA_HOME。
停止(Stop)
点击停止按钮(仅运行中 / 启动中允许):
- 标记「本次启动为主动取消」,避免启动过程中的进程退出被误报为「启动失败」。
- 通过 WMI 查询
Win32_Process(name LIKE 'java%' AND commandLine LIKE '%CATALINA_BASE%',路径中的反斜杠已做 WQL 转义)定位本实例的 java 进程,Stop-Process -Force结束。 - 状态栏回到「已停止」。
重启(Restart)
点击重启按钮:若当前运行中 / 启动中,先执行停止,再执行启动。重启会重建 CATALINA_BASE 配置,但不会重新执行 Maven 打包(若需重新打包请使用「刷新」)。
刷新(Refresh)
点击刷新按钮:若当前运行中 / 启动中,先执行停止,随后执行 mvn clean package -DskipTests -T 1C 重新打包,再执行启动。等价于「重新构建并部署」。
热加载(Hot Reload)
热加载由两个机制协同完成,无需重启 Tomcat:
机制一:JDT.LS 扩展自动同步 .class(war-exploded-class-sync)
通过 package.json 的 contributes.javaExtensions 将 war-exploded-class-sync.jar 加载进 JDT.LS(redhat.java)进程,作为 OSGi bundle 运行:
- bundle 激活后注册 workspace 级
POST_BUILD资源监听器,在每次 JDT 构建完成后收集target/classes下变更的.class(新增 / 修改 / 删除) - 异步 Job 将变更
.class增量同步(复制 / 删除)到target/{finalName}/WEB-INF/classes(即war:exploded解压目录) - 仅处理带
org.eclipse.m2e.core.maven2Nature且packaging=war的工程 - WarTarget 缓存:解析后的 Maven
finalName和目标路径会缓存,避免每次构建都重新加载 Maven 模型(减少 m2e 锁竞争) - 去抖合并:连续保存触发的多次 autobuild 在 300ms 窗口内合并为一次同步 Job,减少 CPU / 磁盘争用
pom.xml变更时自动使缓存失效,确保finalName更新后重新解析
前提:需开启 redhat.java 的 java.autobuild.enabled(默认开启)。保存 .java 后 JDT 自动编译写盘,bundle 在构建完成后同步到部署目录。
机制二:src/main/** 文件监听(防抖 1 秒)+ pom.xml 监听(防抖 5 秒)
VSCode 扩展通过 FileSystemWatcher 监听源码变更,按类型分组处理:
| 文件路径 | 处理方式 |
|---|---|
src/main/resources/**/* |
同步到 deployDir/WEB-INF/classes/(相对 src/main/resources 的路径) |
src/main/webapp/**/* |
同步到 deployDir/ 根(相对 src/main/webapp 的路径) |
pom.xml |
执行 mvn dependency:copy-dependencies -DcleanOutputDirectory=true -DoutputDirectory=target/{finalName}/WEB-INF/lib,将工程依赖复制到部署目录的 WEB-INF/lib(复制前清空旧依赖目录) |
文件 / 文件夹删除时,部署目录中对应的文件或文件夹会被同步删除。Git 原子写入产生的临时文件(.git 后缀 / .git/ 目录)会被自动过滤。
防抖与去重机制
src/main变更:1 秒内多次变更批量处理,同一文件仅保留最新操作(create / change / delete)。pom.xml变更:5 秒内多次变更只处理一次。
.java源文件变更不需要扩展处理——JDT autobuild 编译写盘后,war-exploded-class-syncbundle 自动同步.class到部署目录 + JPDA HotSwap(方法体修改)使变更生效。
部署目录说明
部署目录为工作区下的 target/{finalName},与 writeContextXml 写入的 docBase 一致,即 Tomcat 实际服务的目录:
target/{finalName}/WEB-INF/classes— 编译产物与resources同步目标target/{finalName}/WEB-INF/lib— 依赖(pom.xml变更后复制)target/{finalName}/...—webapp资源同步目标
finalName通过mvn help:evaluate -Dexpression=project.build.finalName取得;它必须与docBase一致,否则热加载会同步到错误目录。
输出通道
插件创建名为 Tomcat 的输出通道,实时显示:
- Tomcat 启动 / 运行 / 停止日志(stdout / stderr)
- 信号文件判定结果(
[信号] 收到 success.tomcat/[信号] 收到 fail.tomcat) - 热加载操作日志
- JDK 路径回退警告
调试(JPDA)
Tomcat 以 jpda run 启动,开放 support.tomcat.debugPort(默认 5005,JDWP,dt_socket)。在 VSCode 中创建 Remote JVM Debug 配置指向该端口,即可断点调试;方法体内的修改可通过 HotSwap 直接生效,无需重启。
内置组件
插件包含两个 Java 组件,打包为 jar 随扩展分发:
| 组件 | 产物 | 运行环境 | 作用 |
|---|---|---|---|
| war-exploded-class-sync | resources/war-exploded-class-sync.jar |
JDT.LS(redhat.java)OSGi bundle | 监听 JDT 构建事件,将 target/classes 下变更的 .class 增量同步到 target/{finalName}/WEB-INF/classes;含 WarTarget 缓存与去抖合并优化 |
| startup-signal-listener | resources/startup-signal-listener.jar |
Tomcat CATALINA_BASE/lib |
注入 server.xml 的 LifecycleListener,在 Server 启动完成时校验所有 webapp context 状态,写 success.tomcat / fail.tomcat 信号文件 |
常见问题
Q: 插件不出现按钮?
A: 检查是否满足激活条件:Windows 环境、已安装 redhat.java、当前工作区包含 pom.xml、为单模块 Maven Web 项目。
Q: 端口被占用?
A: 更改 support.tomcat.port 或 support.tomcat.debugPort 配置项,或点击重启 / 停止释放端口后重试。
Q: 启动后访问报 404?
A: 多半是 target/{finalName} 不存在或内容过旧。请先 mvn package(或点击「刷新」按钮),再启动。
Q: HotSwap 不生效? A: 仅方法体修改支持 HotSwap;新增 / 删除方法、字段等结构性变更需点击「刷新」重新构建并部署。
Q: 能否使用外部 Tomcat?
A: 配置 support.tomcat.home 指向已安装的 Tomcat 目录即可(留空使用内置 Tomcat 9)。
Q: Tomcat 用的 JDK 不对?
A: 插件读取 java.configuration.runtimes 中 default: true 的 JDK 路径。在 VSCode 设置中配置该项即可指定 JDK 版本。
Q: 启动提示 webapp 部署失败?
A: StartupSignalListener 检测到某个 webapp context 未成功启动(状态非 STARTED),输出通道会显示失败 context 列表。检查 web.xml、监听器 / 过滤器类是否缺失、依赖 jar 是否完整。
Q: .class 没有同步到部署目录?
A: 确认 java.autobuild.enabled 已开启;确认项目带有 m2e nature 且 packaging=war。可在 java.jdt.ls.vmargs 中加 -Dccd.debug=true 查看 war-exploded-class-sync bundle 的诊断日志(CCD: 前缀)。
许可证
MIT