
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包部署。原因主要有几点资源管理与隔离应用服务器如BES可以对部署在其上的多个WAR应用进行统一的资源管理线程池、连接池、JNDI等、生命周期监控和类加载隔离。这对于企业级应用的管理和维护至关重要。与服务器特性集成使用WAR包部署可以更好地利用BES提供的高可用集群、会话复制、分布式缓存等企业级特性。这些特性往往需要应用服务器深度的容器集成内嵌容器的Jar包模式难以充分发挥其优势。运维规范很多企业的运维体系是基于传统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我们仍然需要它。所以排除操作需要精细地控制在scopeprovided/scope范围内确保只在打包WAR时生效。3. 项目改造与WAR包生成实操3.1 修改Maven项目配置首先打开JeecgBoot项目根目录的pom.xml文件。修改打包类型找到packaging标签将其值从jar改为war。packagingwar/packaging排除内嵌Tomcat依赖在spring-boot-starter-web依赖中排除spring-boot-starter-tomcat。注意JeecgBoot可能还引入了spring-boot-starter-undertow或spring-boot-starter-jetty作为可选如果存在也需要一并排除。dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId !-- 排除内嵌的Tomcat -- exclusions exclusion groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-tomcat/artifactId /exclusion /exclusions /dependency添加Servlet API依赖关键步骤为了让项目在编译和打包时能通过需要添加Servlet API依赖并将其作用域设为provided因为BES服务器运行时本身会提供这些类。dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version3.1.0/version !-- 版本需与BES服务器兼容通常3.1或4.0 -- scopeprovided/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。注释或移除内嵌服务器配置由于不再使用内嵌服务器原来关于server.port和server.servlet.context-path的配置将由BES管理。通常的做法是注释掉它们或者在BES的控制台部署时指定上下文路径。# server: # port: 8080 # servlet: # context-path: /jeecg-boot确保其他配置兼容检查数据源spring.datasource、Redisspring.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应用服务器已经安装完毕。部署前需要确认几个关键点JDK版本通过BES控制台或查看bes.sh/bat脚本确认BES使用的JDK版本。JeecgBoot 3.x 通常需要JDK 8或11确保版本匹配。可以在BES的bin目录下执行./java -version查看。BES实例状态确保你要部署的BES实例Server已经启动并运行正常。管理控制台登录BES的管理控制台默认端口通常是9060或9080熟悉部署和管理功能的位置。4.2 数据源与JNDI配置推荐做法在企业环境中更推荐在BES服务器上配置JNDI数据源然后在应用中通过JNDI名称来获取数据库连接。这样做的好处是数据源由服务器统一管理支持连接池优化、监控并且应用配置与服务器环境解耦。在BES控制台配置数据源找到“资源”-“JDBC提供程序”或“数据源”配置页面。创建一个新的JDBC提供程序选择与你数据库如MySQL匹配的驱动类路径。你需要提前将数据库驱动JAR包如mysql-connector-java-8.0.xx.jar上传到BES服务器的特定目录如[BES安装目录]/lib或[BES实例目录]/lib。基于该JDBC提供程序创建一个数据源。填写数据库URL、用户名、密码等关键信息。并设置一个JNDI名称例如jdbc/jeecgDB。配置连接池参数如初始连接数、最大连接数、超时时间等。这些参数需要根据你的应用实际负载进行调整。修改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?useUnicodetruecharacterEncodingUTF-8 # username: root # password: 123456 # driver-class-name: com.mysql.cj.jdbc.Driver注意java:comp/env/是标准的JNDI上下文前缀后面跟着你在BES中配置的JNDI名称。配置资源引用可选但建议 在src/main/webapp/WEB-INF/目录下如果没有则创建创建一个web.xml文件声明对JNDI数据源的引用。?xml version1.0 encodingUTF-8? web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaee xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd version3.1 resource-ref descriptionJeecgBoot DataSource/description res-ref-namejdbc/jeecgDB/res-ref-name res-typejavax.sql.DataSource/res-type res-authContainer/res-auth /resource-ref /web-app这个步骤不是绝对必须的但对于某些遵循严格EE规范的应用服务器明确声明资源引用是好的实践。5. WAR包部署与启动流程5.1 通过BES控制台部署这是最常用的图形化部署方式。上传WAR包登录BES管理控制台导航到“应用程序”-“安装新应用程序”。选择“本地文件系统”点击“浏览”上传我们之前生成的jeecg-boot-xxx.war文件。配置部署选项上下文根这是应用访问的路径。例如设置为/jeecg那么应用访问地址就是http://服务器IP:端口/jeecg。你可以保持与原来server.servlet.context-path一致或者根据需求修改。虚拟主机一般选择default_host。模块确保WAR文件被正确识别为一个Web模块。映射资源引用在安装过程的“映射资源引用到资源”步骤中系统可能会自动发现我们在web.xml中声明的jdbc/jeecgDB。你需要将它映射到在BES服务器上创建的实际数据源同名。完成安装按照向导完成安装。安装成功后应用会出现在“企业应用程序”列表中状态通常是“已停止”。启动应用选中你的应用如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.NoClassDefFoundError或java.lang.NoSuchMethodError错误通常涉及Servlet、JSP、JSTL、Jackson、Logging等常见API。根因分析BES作为Java EE服务器已经提供了Servlet、JSP、EL、JAXB等标准API的实现包。而我们打WAR包时如果Maven依赖中包含了这些库例如javax.servlet-api,jstl,jackson-databind等并且没有正确设置scopeprovided/scope它们就会被打包进WAR的WEB-INF/lib下。部署时BES的类加载器可能会优先加载WAR包中的版本而该版本可能与BES环境不兼容导致冲突。解决方案彻底检查依赖使用mvn dependency:tree命令生成详细的依赖树仔细检查是否有服务器应提供的JAR被打了进来。设置provided范围对于所有已知的Java EE API依赖如Servlet、JSP、JSTL、JAXB、JAX-WS等以及可能与BES内置库冲突的通用库如Jackson、Log4j2/SLF4J绑定器在pom.xml中将其作用域设置为provided。!-- 示例排除可能冲突的库 -- dependency groupIdcom.fasterxml.jackson.core/groupId artifactIdjackson-databind/artifactId version${jackson.version}/version scopeprovided/scope !-- 如果BES自带 -- /dependency使用BES的共享库对于某些版本敏感的通用库如Apache Commons系列、Guava如果BES提供了共享库功能可以将这些JAR包配置为BES的共享库然后让应用去引用而不是打包进WAR。这需要查阅BES的管理手册。调整类加载策略在BES控制台中找到你部署的应用在“类加载和更新检测”设置中尝试将“类加载器模式”从默认的PARENT_FIRST改为PARENT_LAST。这会让应用优先加载WAR包WEB-INF/lib和WEB-INF/classes中的类然后再委托给父加载器BES服务器。这是一个非常有效的调试手段但生产环境需谨慎评估因为它可能掩盖更深层次的依赖问题。6.2 数据源连接失败症状应用启动时报数据库连接错误如Cannot create connection to database。排查步骤检查BES数据源状态在BES控制台中测试你配置的数据源连接是否成功。检查JNDI名称确认应用application.yml中spring.datasource.jndi-name的值与BES中数据源配置的JNDI名称完全一致包括大小写。检查驱动类确认BES中JDBC提供程序配置的驱动类路径正确且驱动JAR包已放置在BES能加载的位置。查看详细日志开启BES更详细的JDBC日志查看连接尝试的详细信息。6.3 静态资源或前端页面404症状应用能登录但部分JS、CSS文件加载失败或者某些页面打开空白或404。排查步骤检查上下文根确认访问的URL路径是否正确包含了部署时设置的上下文根。检查静态资源路径JeecgBoot的前端资源通常打包在WAR包内。检查BES日志看是否有关于资源文件找不到的警告。可能是Spring Boot的静态资源映射在Servlet容器中需要额外配置。不过JeecgBoot通常处理得较好。浏览器开发者工具使用浏览器的网络检查工具F12查看具体是哪个资源请求失败了错误码是什么404, 500等这能提供最直接的线索。6.4 性能调优建议部署成功后为了获得更好的生产环境性能可以考虑以下几点BES JVM参数调优在BES的服务器配置中调整JVM堆内存-Xms,-Xmx、元空间-XX:MetaspaceSize、垃圾回收器参数等。对于JeecgBoot这类内存消耗中等的应用初始堆大小可以设为2G最大堆大小设为4G或根据物理内存调整。数据源连接池调优根据预估的并发用户数合理设置BES数据源连接池的最大连接数、最小连接数、连接超时和空闲超时时间。避免连接数不足导致等待或连接数过多浪费资源。BES线程池调优调整BES Web容器的线程池大小最小/最大工作线程数以匹配应用的并发请求处理能力。JeecgBoot自身缓存确保Redis等缓存服务配置正确且高效JeecgBoot的权限、字典等数据会利用缓存提升性能。整个集成部署过程从项目改造到服务器调优考验的是对Spring Boot机制、WAR包规范以及宝兰德BES服务器特性的综合理解。最花时间的往往不是步骤本身而是遇到问题时的排查和定位。建议在测试环境充分验证并保留详细的部署和配置文档这对于后续的维护和问题回溯至关重要。