ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

JeecgBoot项目迁移宝兰德BES:WAR包部署与国产化适配实战

2026/8/12 18:43:31 拓冰建站 浏览量
JeecgBoot项目迁移宝兰德BES:WAR包部署与国产化适配实战

1. 项目概述与背景

最近在帮一个客户做项目迁移,他们原来的系统是基于JeecgBoot开发的,运行在Tomcat上,现在因为一些合规和性能要求,需要将整个应用迁移到国产的宝兰德应用服务器(BES AppServer)上。这个需求其实挺有代表性的,随着国产化替代的浪潮,很多使用Spring Boot框架(包括像JeecgBoot这样的低代码平台)开发的项目,都面临着从开源中间件向国产商用中间件迁移的挑战。JeecgBoot本身是一个优秀的快速开发平台,但它默认的打包和部署方式主要是面向Tomcat、Jetty这类Servlet容器的。而宝兰德BES作为一款企业级的Java EE应用服务器,在部署Spring Boot应用,特别是打成WAR包部署时,会有一些特定的配置和注意事项,并不是简单地把jar换成war扔进去就能跑的。

这个“集成部署方案”,核心要解决的就是如何让一个标准的JeecgBoot项目,经过适当的改造和配置,能够稳定、高效地运行在宝兰德BES应用服务器环境中。这中间涉及到项目结构的调整、依赖的排除、配置文件的修改、以及BES服务器本身的一些优化设置。整个过程走下来,我发现网上虽然有一些零散的教程,但要么不够详细,要么就是针对普通Spring Boot项目的,对于JeecgBoot这种集成了大量自身组件(比如Online表单、代码生成器、报表等)的平台,直接套用可能会踩坑。所以,我把自己从环境准备、项目改造、打包部署到问题排查的全过程梳理出来,希望能给遇到类似需求的同行一个清晰的参考。

2. 核心需求与方案选型解析

2.1 为什么选择WAR包部署而非可执行JAR?

这是首先要明确的问题。JeecgBoot默认生成的是可执行的Spring Boot Jar包,里面内嵌了Tomcat容器。这种方式部署简单,java -jar一行命令就起来了。但是,在宝兰德BES这类标准的Java EE应用服务器环境中,通常更推荐使用WAR包部署。原因主要有几点:

  1. 资源管理与隔离:应用服务器(如BES)可以对部署在其上的多个WAR应用进行统一的资源管理(线程池、连接池、JNDI等)、生命周期监控和类加载隔离。这对于企业级应用的管理和维护至关重要。
  2. 与服务器特性集成:使用WAR包部署,可以更好地利用BES提供的高可用集群、会话复制、分布式缓存等企业级特性。这些特性往往需要应用服务器深度的容器集成,内嵌容器的Jar包模式难以充分发挥其优势。
  3. 运维规范:很多企业的运维体系是基于传统WAR包部署流程建立的(如通过控制台部署、启停、更新)。采用WAR包更符合现有的运维习惯和工具链。

因此,我们的方案核心就是:将JeecgBoot项目改造为可部署在Servlet容器中的WAR包形式,并针对宝兰德BES进行适配性配置。

2.2 方案整体思路与关键决策点

整个方案的思路可以概括为:“一改、二排、三配、四调”。

  • 一改(项目改造):修改项目打包方式为WAR,并让主启动类继承SpringBootServletInitializer。这是让Spring Boot应用支持外部Servlet容器的标准做法。
  • 二排(依赖排除):排除Spring Boot内嵌的Tomcat依赖,避免与BES服务器自带的Servlet容器API发生冲突。这是最关键也最容易出错的一步。
  • 三配(配置调整):调整application.yml中的服务器相关配置,特别是端口、上下文路径等,使其适应在BES中运行的模式(通常由BES管理端口和路径)。
  • 四调(服务器调优):根据JeecgBoot应用的特点(如大量在线开发功能、可能的高并发查询),对BES服务器的JDK参数、线程池、数据源连接池等进行针对性调优。

这里有一个重要的决策点:如何处理JeecgBoot内置的spring-boot-starter-tomcat依赖?我们选择在打包WAR时排除它,但需要注意的是,在开发阶段(比如用IDE直接运行JeecgSystemApplication),我们仍然需要它。所以,排除操作需要精细地控制在<scope>provided</scope>范围内,确保只在打包WAR时生效。

3. 项目改造与WAR包生成实操

3.1 修改Maven项目配置

首先,打开JeecgBoot项目根目录的pom.xml文件。

  1. 修改打包类型:找到<packaging>标签,将其值从jar改为war

    <packaging>war</packaging>
  2. 排除内嵌Tomcat依赖:在spring-boot-starter-web依赖中,排除spring-boot-starter-tomcat。注意,JeecgBoot可能还引入了spring-boot-starter-undertowspring-boot-starter-jetty作为可选,如果存在也需要一并排除。

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- 排除内嵌的Tomcat --> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency>
  3. 添加Servlet API依赖(关键步骤):为了让项目在编译和打包时能通过,需要添加Servlet API依赖,并将其作用域设为provided,因为BES服务器运行时本身会提供这些类。

    <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <!-- 版本需与BES服务器兼容,通常3.1或4.0 --> <scope>provided</scope> </dependency>

    注意:宝兰德BES的版本不同,可能基于不同版本的Servlet规范。务必查阅BES的官方文档,确认其兼容的Servlet API版本。使用不匹配的版本可能导致类加载错误或运行时异常。

3.2 修改主启动类

找到你的主启动类(通常是JeecgSystemApplication),让它继承SpringBootServletInitializer,并重写configure方法。

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @SpringBootApplication public class JeecgSystemApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { // 指向原有的Spring Boot主启动类 return application.sources(JeecgSystemApplication.class); } public static void main(String[] args) { SpringApplication.run(JeecgSystemApplication.class, args); } }

这个修改的作用是,当WAR包被部署到Servlet容器(BES)中时,容器会调用configure方法来引导Spring Boot应用的启动。

3.3 调整应用配置文件

修改src/main/resources/application.yml(或application.properties)。

  1. 注释或移除内嵌服务器配置:由于不再使用内嵌服务器,原来关于server.portserver.servlet.context-path的配置将由BES管理。通常的做法是注释掉它们,或者在BES的控制台部署时指定上下文路径。
    # server: # port: 8080 # servlet: # context-path: /jeecg-boot
  2. 确保其他配置兼容:检查数据源(spring.datasource)、Redis(spring.redis)等配置。它们的连接地址、端口等信息需要指向BES服务器所在环境中的实际服务地址,而不是localhost。例如,数据库可能部署在另一台服务器上。

3.4 执行打包命令

在项目根目录下,使用Maven命令进行打包:

mvn clean package -DskipTests

打包成功后,在target目录下会生成一个[你的项目名]-[版本号].war文件(例如jeecg-boot-3.4.4.war)。这个WAR包就是我们最终要部署到宝兰德BES上的文件。

实操心得:在打包前,建议先执行mvn clean compile检查是否有编译错误。有时候依赖排除不干净,会导致编译时找不到相关的类。另外,-DskipTests参数可以跳过测试,加快打包速度,但在正式环境部署前,务必确保单元测试和集成测试通过。

4. 宝兰德BES服务器环境准备与配置

4.1 BES安装与基础环境检查

假设宝兰德BES应用服务器已经安装完毕。部署前,需要确认几个关键点:

  1. JDK版本:通过BES控制台或查看bes.sh/bat脚本,确认BES使用的JDK版本。JeecgBoot 3.x 通常需要JDK 8或11,确保版本匹配。可以在BES的bin目录下执行./java -version查看。
  2. BES实例状态:确保你要部署的BES实例(Server)已经启动并运行正常。
  3. 管理控制台:登录BES的管理控制台(默认端口通常是90609080),熟悉部署和管理功能的位置。

4.2 数据源与JNDI配置(推荐做法)

在企业环境中,更推荐在BES服务器上配置JNDI数据源,然后在应用中通过JNDI名称来获取数据库连接。这样做的好处是数据源由服务器统一管理,支持连接池优化、监控,并且应用配置与服务器环境解耦。

  1. 在BES控制台配置数据源

    • 找到“资源”->“JDBC提供程序”或“数据源”配置页面。
    • 创建一个新的JDBC提供程序,选择与你数据库(如MySQL)匹配的驱动类路径。你需要提前将数据库驱动JAR包(如mysql-connector-java-8.0.xx.jar)上传到BES服务器的特定目录(如[BES安装目录]/lib[BES实例目录]/lib)。
    • 基于该JDBC提供程序,创建一个数据源。填写数据库URL、用户名、密码等关键信息。并设置一个JNDI名称,例如jdbc/jeecgDB
    • 配置连接池参数,如初始连接数、最大连接数、超时时间等。这些参数需要根据你的应用实际负载进行调整。
  2. 修改JeecgBoot应用配置: 在application.yml中,将原来的Spring Boot数据源配置改为JNDI查找方式。

    spring: datasource: jndi-name: java:comp/env/jdbc/jeecgDB # 注释掉原有的 url, username, password, driver-class-name 配置 # url: jdbc:mysql://localhost:3306/jeecg-boot?useUnicode=true&characterEncoding=UTF-8 # username: root # password: 123456 # driver-class-name: com.mysql.cj.jdbc.Driver

    注意java:comp/env/是标准的JNDI上下文前缀,后面跟着你在BES中配置的JNDI名称。

  3. 配置资源引用(可选但建议): 在src/main/webapp/WEB-INF/目录下(如果没有则创建),创建一个web.xml文件,声明对JNDI数据源的引用。

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <resource-ref> <description>JeecgBoot DataSource</description> <res-ref-name>jdbc/jeecgDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> </web-app>

    这个步骤不是绝对必须的,但对于某些遵循严格EE规范的应用服务器,明确声明资源引用是好的实践。

5. WAR包部署与启动流程

5.1 通过BES控制台部署

这是最常用的图形化部署方式。

  1. 上传WAR包:登录BES管理控制台,导航到“应用程序”->“安装新应用程序”。选择“本地文件系统”,点击“浏览”上传我们之前生成的jeecg-boot-xxx.war文件。
  2. 配置部署选项
    • 上下文根:这是应用访问的路径。例如,设置为/jeecg,那么应用访问地址就是http://服务器IP:端口/jeecg。你可以保持与原来server.servlet.context-path一致,或者根据需求修改。
    • 虚拟主机:一般选择default_host
    • 模块:确保WAR文件被正确识别为一个Web模块。
  3. 映射资源引用:在安装过程的“映射资源引用到资源”步骤中,系统可能会自动发现我们在web.xml中声明的jdbc/jeecgDB。你需要将它映射到在BES服务器上创建的实际数据源(同名)。
  4. 完成安装:按照向导完成安装。安装成功后,应用会出现在“企业应用程序”列表中,状态通常是“已停止”。
  5. 启动应用:选中你的应用(如jeecg-boot-xxx),点击“启动”。控制台会显示启动日志。如果启动成功,状态会变为“已启动”。

5.2 通过命令行或脚本部署

对于自动化运维场景,可以通过BES提供的命令行工具(如wsadmin)或直接将WAR包放到BES的自动部署目录(如[BES实例目录]/webapps/)下。后一种方式BES会自动解压并部署,但可控性较差,生产环境不建议。

5.3 验证部署成功

应用启动后,通过浏览器访问你的应用。例如,如果BES的HTTP端口是9080,上下文根是/jeecg,那么访问地址就是http://your-server-ip:9080/jeecg

你应该能看到JeecgBoot的登录页面。尝试使用管理员账号登录,并测试几个核心功能,如用户管理、在线表单开发、菜单配置等,确保所有功能在BES环境下运行正常。

6. 常见问题与深度排查指南

将JeecgBoot部署到BES的过程很少一帆风顺,以下是我在实际操作中遇到的一些典型问题及解决方法。

6.1 类冲突与NoClassDefFoundError/NoSuchMethodError

这是最常见的问题,根本原因是应用WAR包中的库与BES服务器自带的库版本冲突。

  • 症状:应用启动失败,在BES日志(通常位于[BES实例目录]/logs/[server_name]/SystemOut.log)中看到java.lang.NoClassDefFoundErrorjava.lang.NoSuchMethodError,错误通常涉及Servlet、JSP、JSTL、Jackson、Logging等常见API。
  • 根因分析:BES作为Java EE服务器,已经提供了Servlet、JSP、EL、JAXB等标准API的实现包。而我们打WAR包时,如果Maven依赖中包含了这些库(例如javax.servlet-api,jstl,jackson-databind等),并且没有正确设置<scope>provided</scope>,它们就会被打包进WAR的WEB-INF/lib下。部署时,BES的类加载器可能会优先加载WAR包中的版本,而该版本可能与BES环境不兼容,导致冲突。
  • 解决方案
    1. 彻底检查依赖:使用mvn dependency:tree命令生成详细的依赖树,仔细检查是否有服务器应提供的JAR被打了进来。
    2. 设置provided范围:对于所有已知的Java EE API依赖(如Servlet、JSP、JSTL、JAXB、JAX-WS等),以及可能与BES内置库冲突的通用库(如Jackson、Log4j2/SLF4J绑定器),在pom.xml中将其作用域设置为provided
      <!-- 示例:排除可能冲突的库 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> <scope>provided</scope> <!-- 如果BES自带 --> </dependency>
    3. 使用BES的共享库:对于某些版本敏感的通用库(如Apache Commons系列、Guava),如果BES提供了共享库功能,可以将这些JAR包配置为BES的共享库,然后让应用去引用,而不是打包进WAR。这需要查阅BES的管理手册。
    4. 调整类加载策略:在BES控制台中,找到你部署的应用,在“类加载和更新检测”设置中,尝试将“类加载器模式”从默认的PARENT_FIRST改为PARENT_LAST。这会让应用优先加载WAR包WEB-INF/libWEB-INF/classes中的类,然后再委托给父加载器(BES服务器)。这是一个非常有效的调试手段,但生产环境需谨慎评估,因为它可能掩盖更深层次的依赖问题。

6.2 数据源连接失败

  • 症状:应用启动时报数据库连接错误,如Cannot create connection to database
  • 排查步骤
    1. 检查BES数据源状态:在BES控制台中,测试你配置的数据源连接是否成功。
    2. 检查JNDI名称:确认应用application.ymlspring.datasource.jndi-name的值,与BES中数据源配置的JNDI名称完全一致,包括大小写。
    3. 检查驱动类:确认BES中JDBC提供程序配置的驱动类路径正确,且驱动JAR包已放置在BES能加载的位置。
    4. 查看详细日志:开启BES更详细的JDBC日志,查看连接尝试的详细信息。

6.3 静态资源或前端页面404

  • 症状:应用能登录,但部分JS、CSS文件加载失败,或者某些页面打开空白或404。
  • 排查步骤
    1. 检查上下文根:确认访问的URL路径是否正确包含了部署时设置的上下文根。
    2. 检查静态资源路径:JeecgBoot的前端资源通常打包在WAR包内。检查BES日志,看是否有关于资源文件找不到的警告。可能是Spring Boot的静态资源映射在Servlet容器中需要额外配置。不过,JeecgBoot通常处理得较好。
    3. 浏览器开发者工具:使用浏览器的网络检查工具(F12),查看具体是哪个资源请求失败了,错误码是什么(404, 500等),这能提供最直接的线索。

6.4 性能调优建议

部署成功后,为了获得更好的生产环境性能,可以考虑以下几点:

  1. BES JVM参数调优:在BES的服务器配置中,调整JVM堆内存(-Xms,-Xmx)、元空间(-XX:MetaspaceSize)、垃圾回收器参数等。对于JeecgBoot这类内存消耗中等的应用,初始堆大小可以设为2G,最大堆大小设为4G或根据物理内存调整。
  2. 数据源连接池调优:根据预估的并发用户数,合理设置BES数据源连接池的最大连接数最小连接数连接超时空闲超时时间。避免连接数不足导致等待,或连接数过多浪费资源。
  3. BES线程池调优:调整BES Web容器的线程池大小(最小/最大工作线程数),以匹配应用的并发请求处理能力。
  4. JeecgBoot自身缓存:确保Redis等缓存服务配置正确且高效,JeecgBoot的权限、字典等数据会利用缓存提升性能。

整个集成部署过程,从项目改造到服务器调优,考验的是对Spring Boot机制、WAR包规范以及宝兰德BES服务器特性的综合理解。最花时间的往往不是步骤本身,而是遇到问题时的排查和定位。建议在测试环境充分验证,并保留详细的部署和配置文档,这对于后续的维护和问题回溯至关重要。