# 本地 Tomcat 运行与 TongWeb 打包并存设计 ## 背景 当前项目已经被调整为统一的 TongWeb `war` 交付模式,这会导致本地开发时也必须围绕 TongWeb 组织启动流程,不符合当前开发诉求。 本次目标是同时保留两条链路: - 本地开发运行继续使用内嵌 Tomcat - 打包交付继续支持服务器上的 TongWeb 并且要求一次 `mvn package` 同时产出本地运行所需的 `jar` 和服务器部署所需的 `war`。 ## 目标 - 保留 `IDEA`、`mvn spring-boot:run`、本地脚本直启后端的开发体验 - 保留面向 TongWeb 的 `war` 交付方式 - `mvn package` 后同时得到 `ruoyi-admin.jar` 与 `ruoyi-admin.war` - 本地不强依赖安装 TongWeb - 服务器部署脚本继续只消费 `war` ## 非目标 - 不新增第二个后端启动模块 - 不拆分额外的部署工程 - 不修改前端构建方式 - 不引入“兼容模式”“降级模式”之类额外分支逻辑 ## 设计方案 ### 1. 构建产物设计 `ruoyi-admin` 恢复为以 `jar` 为主产物的 Spring Boot 应用,用于本地开发运行。 在同一个 Maven 模块中补充 `war` 打包步骤,使一次 `mvn package` 后同时得到: - `ruoyi-admin/target/ruoyi-admin.jar` - `ruoyi-admin/target/ruoyi-admin.war` 这样本地和服务器都从同一套源码构建,但消费不同产物: - 本地消费 `jar` - 服务器消费 `war` ### 2. 依赖设计 为了保证本地可继续走内嵌 Tomcat: - 恢复 Web 模块中的内嵌 Tomcat 依赖链 - 保持 `spring-boot:run` 与 `java -jar` 均可正常工作 为了保证 TongWeb 外部容器部署: - 打出的 `war` 不能把容器自身实现错误打包成部署冲突形式 - `Servlet API` 继续按外部容器提供的思路处理 本质上,本地运行和 TongWeb 部署共享同一套业务代码,但运行容器不同。 ### 3. 启动脚本设计 #### 本地脚本 `bin/restart_java_backend.sh` 恢复为本地开发脚本: - 执行 Maven 打包 - 使用 `ruoyi-admin.jar` - 通过 `java -jar` 管理本地后端进程 这条链路不再依赖 `TONGWEB_HOME`。 #### 生产脚本 以下脚本保持 TongWeb 交付模型: - `bin/prod/restart_java.sh` - `bin/prod/deploy_from_package.sh` - `bin/prod/deploy_release.sh` 它们继续只处理 `ruoyi-admin.war`,不回退到 `jar`。 ### 4. 本地与服务器联调设计 本地开发时不要求本机安装 TongWeb。 如果需要验证 TongWeb 运行环境,只通过两种方式完成: - 打包后部署到服务器 TongWeb 验证 - 本地系统直接调用服务器上已部署的 TongWeb 地址联调 这意味着: - 本地开发链路只围绕 `jar + Tomcat` - 服务器部署链路只围绕 `war + TongWeb` ## 验证方案 ### 构建验证 执行: ```sh mvn -pl ruoyi-admin -am package -DskipTests ``` 确认同时存在: - `ruoyi-admin/target/ruoyi-admin.jar` - `ruoyi-admin/target/ruoyi-admin.war` ### 本地运行验证 执行: ```sh sh bin/restart_java_backend.sh restart ``` 确认本地以 `java -jar` 正常运行。 ### TongWeb 脚本验证 执行: ```sh sh bin/prod/restart_java_test.sh sh bin/prod/deploy_from_package_test.sh ``` 确认 TongWeb 侧仍围绕 `war` 工作。 ## 影响范围 - `ruoyi-admin` Maven 打包配置 - Web 相关模块的容器依赖声明 - 本地后端脚本 - 生产 TongWeb 脚本 - 运行文档与实施记录 ## 结论 本方案采用最短路径实现“双产物、双运行链路并存”: - 本地运行继续走内嵌 Tomcat - 服务器部署继续走 TongWeb - 一次打包同时产出 `jar` 与 `war` 在不新增模块、不扩散复杂度的前提下,满足开发与部署两端的实际需要。