本文说明如何将当前 ChestnutCMS 后端构建为可部署到外部 Servlet 容器的 WAR 包。
| 项目 | 要求 |
|---|---|
| 构建目录 | 仓库根目录,即包含顶层 pom.xml 的目录 |
| JDK | JDK 17,java、javac 和 Maven 应使用同一套 JDK |
| 构建工具 | Maven,能够访问项目配置的依赖仓库 |
| 外部 Web 容器 | Jakarta Servlet 6.1 或更高版本 |
当前代码使用 Spring Boot 4.0.7、Spring Framework 7.0.8,编译目标为 Java 17。不能使用 JDK 8 构建或运行。
先检查本机实际使用的 Java 版本:
java -version
javac -version
mvn -version
重点核对 mvn -version 中的 Java version 和 Java home。若本机有多个 JDK,先设置 JAVA_HOME 和 PATH,再执行构建。
项目已经具备外部容器部署所需配置,无需手工修改打包方式或添加 web.xml:
chestnut-admin/pom.xml 默认生成 JAR;启用 war profile 后,chestnut.admin.packaging 变为 war。spring-boot-starter-tomcat 和 jakarta.servlet-api 在 WAR profile 中声明为 provided。ChestnutServletInitializer 继承 SpringBootServletInitializer,由外部容器初始化 ChestnutApplication。maven-war-plugin 允许项目不提供 web.xml。repackage,最终产物名称固定为 chestnut-admin.war。Spring Boot 的可执行 WAR 可能包含 WEB-INF/lib-provided/,这是正常的打包结果。该目录用于保留 provided 依赖;部署到 BES 时不要将这些 JAR 手工搬到 WEB-INF/lib/ 或 BES 的 lib/ 下。
在仓库根目录执行:
mvn -Pwar,media-linux64 -pl chestnut-admin -am clean package -Dmaven.test.skip=true
参数含义:
| 参数 | 作用 |
|---|---|
-Pwar | 启用外部 Servlet 容器使用的 WAR 打包配置 |
-Pmedia-linux64 | 选择 Linux x86_64 的 JAVE 媒体处理原生组件 |
-pl chestnut-admin | 只选择后台入口模块 |
-am | 同时构建入口依赖的其他项目模块 |
clean package | 清理旧构建产物并重新打包 |
-Dmaven.test.skip=true | 跳过测试编译和执行,适用于已完成测试的交付构建 |
多个 profile 可写在同一个 -P 参数中。上面的命令也可写为 -Pwar -Pmedia-linux64。
如果需要编译测试代码但不执行测试,将 -Dmaven.test.skip=true 改为 -DskipTests;需要执行测试时移除跳过参数,并准备对应测试所需的环境。
只验证应用启动,或需要保留默认多平台媒体组件时采用的命令:
mvn -Pwar -pl chestnut-admin -am package -Dmaven.test.skip=true
chestnut-cms-media 的 media-all profile 默认启用,会包含 Linux、Windows、macOS 的媒体组件;显式选择该模块的单平台 profile 后,默认 profile 会停用。
| 部署目标 | 媒体 profile |
|---|---|
| Linux x86_64 | media-linux64 |
| Windows x86_64 | media-win64 |
| macOS Apple Silicon | media-osxm1 |
| macOS Intel | media-osx64 |
应按部署服务器选择,而不是按构建机选择。其他 CPU 架构需要另行准备匹配的媒体处理组件。
构建日志应出现 BUILD SUCCESS。产物位于:
chestnut-admin/target/chestnut-admin.war
不要将同目录下的 .original 文件当作最终交付包。
检查 WAR 中是否存在入口类:
jar tf chestnut-admin/target/chestnut-admin.war | grep 'WEB-INF/classes/com/chestnut/ChestnutServletInitializer.class'
检查清单和项目类的编译版本:
unzip -p chestnut-admin/target/chestnut-admin.war META-INF/MANIFEST.MF
javap -verbose -classpath chestnut-admin/target/classes com.chestnut.ChestnutApplication | grep 'major version'
清单应包含当前 Spring Boot 版本和 Start-Class: com.chestnut.ChestnutApplication;Java 17 项目类的 major version 应为 61。
传输前后核对文件校验值。Linux 使用:
sha256sum chestnut-admin/target/chestnut-admin.war
macOS 使用:
shasum -a 256 chestnut-admin/target/chestnut-admin.war
WAR 中会带有 application.yml 和各 profile 配置,但服务器的数据库、Redis、目录和日志配置建议通过外置文件提供。
WAR 只包含后端,不包含 chestnut-ui-vue3 构建后的后台管理页面。访问 /login/config 得到正常 JSON 只能证明后端接口可用;后台页面需要单独构建前端并由 Nginx 提供静态资源。
| 现象 | 检查方式 |
|---|---|
最终只有 .jar | 确认启用了 war profile,检查的目录是 chestnut-admin/target |
| 找不到其他 Chestnut 模块依赖 | 从仓库根目录执行,并保留 -am |
release version 17 not supported | 检查 mvn -version,Maven 可能仍在使用旧 JDK |
| 容器部署后没有 Spring 上下文或接口始终 404 | 确认容器提供 Jakarta Servlet 6.1,检查入口类和完整启动日志 |
Unsupported class file major version 68/69 | 先定位具体 JAR 和类路径;68 对应 Java 24,69 对应 Java 25,也可能来自依赖的 META-INF/versions/ 多版本类,不能直接据此认定项目使用了对应 JDK 编译 |
| 音视频处理不可用 | 检查媒体 profile 是否与目标操作系统和 CPU 匹配,并单独验证媒体处理功能 |