嵌入式Tomcat从哪加载WAR包?如何排查旧版本应用加载问题
嵌入式Tomcat持续加载旧版本应用排查方案
以下排查路径按操作成本从低到高排序,可逐步验证:
1. 直接确认当前运行类的实际加载路径
这是最快的定位方式,不用猜配置:
- 临时加一个调试接口/在启动逻辑里加日志,调用对应代码获取类的来源:
启动后控制台会直接打印该类所在jar/war的绝对路径,一眼就能看出来是加载了旧构建产物、本地缓存依赖还是残留的临时文件。// 替换成你最近修改过的业务类即可 System.out.println(YourBizClass.class.getProtectionDomain().getCodeSource().getLocation()); - 如果不想改代码,给JVM加启动参数
-verbose:class,启动后控制台会打印每个类的加载路径,搜你修改过的业务类全限定名即可定位来源。
2. 清理嵌入式Tomcat的临时工作目录
这是同代码版本下加载旧应用的最高频诱因:
- 嵌入式Tomcat如果初始化时没有手动调用
tomcat.setBaseDir()指定固定的基础目录,会默认使用系统临时目录作为工作根路径:Windows下对应C:\Users\<用户名>\AppData\Local\Temp\,Linux/macOS对应/tmp/,目录名一般带tomcat+端口号/随机字符串特征。 - 直接删除所有匹配特征的Tomcat临时目录——这些目录里存着之前启动时解压的war包内容,Tomcat启动时如果发现目录已存在,默认不会重新解压新构建的war,会直接复用旧文件。
- 可以在Tomcat初始化代码里加日志打印
((StandardContext)webapp).getDocBase()和tomcat.getServer().getCatalinaBase(),确认当前实例实际读取的web应用路径、工作目录路径和你预期的最新构建路径一致。
3. 验证构建产物与依赖缓存有效性
排除代码逻辑没问题,但构建出来的本身就是旧包的情况:
- 去项目构建输出目录(一般是
target/或build/),检查生成的war包修改时间是否是最新构建时间,解压war包找到你修改过的类文件,确认修改时间匹配;如果不匹配,说明构建时没执行clean步骤,残留了旧的class文件,重新执行mvn clean package/对应构建命令即可。 - 如果项目依赖了内部快照版本(SNAPSHOT)的jar包,检查本地maven/gradle缓存目录里的对应依赖是否是最新版本,构建时加
-U参数强制拉取最新快照依赖,避免本地缓存的旧依赖被打进war包。
4. 排查进程与启动配置错误
- 先查端口占用:执行对应系统的端口查进程命令,确认你要使用的端口没有被之前残留的Tomcat进程占用——很多时候旧进程没关干净,新启动的实例因为端口占用根本没成功启动,访问的一直是后台挂着的旧版本进程。
- Windows:执行
netstat -ano | findstr <你的端口号>,根据查到的PID去任务管理器结束进程 - Linux/macOS:执行
lsof -i:<你的端口号>,查到PID后执行kill -9 <PID>
- Windows:执行
- 检查IDE启动配置:确认启动的是你写了嵌入式Tomcat初始化逻辑的main方法,不是IDE里之前配置的外部Tomcat实例,避免跑错启动入口。
内容的提问来源于stack exchange,提问作者Mr Smith
相关产品推荐
相关产品推荐

