2022年的Java老项目,代码完整却跑不起来——4个致命缺失与避坑清单
老炮踩坑录 · F01 · 翻车现场系列
· 基于「企业融合评估系统」真实源码
· 代码只占"能跑起来"的30%,剩下70%是环境、配置、数据、外部依赖。这些没了,代码就是废铁。
引子
记得我离职大概三个月的时候,前同事发来消息:
"老哥,你那个企业融合评估的项目代码能给我一份吗?公司要交接。"
我翻出硬盘,把整个工程目录打包发过去。
半小时后,他回了句:
"跑不起来,数据库脚本呢?"
我愣了一下——我手上也没有数据库脚本。
那个库是DBA在测试环境直接建的,建表语句没走过Git,也没人用 mysqldump 导出过DDL。我本地当年跑的是直连测试库,测试环境到期回收后,库就没了。
一个2022年的项目——Spring Boot、MyBatis-Plus、RabbitMQ…代码完整,Maven能编译通过。
但第一把就没跑起来。
不是代码有Bug,是缺的东西比较多。
我有什么
先说说"看起来什么都有"的那部分:
✅ 完整的源码(Git 全量提交记录)
✅ pom.xml 依赖完整,mvn compile 能过
✅ application.yml + application-test.yml 配置文件在
✅ 11个 Excel 模板在 resources/excel/ 下
✅ 前端静态页面在 static/ 下(51个HTML + 20个JS + 20个CSS)
✅ 24个 Mapper XML 在 resources/mapping/ 下
✅ 打包方式:WAR,外置 Tomcat 部署
你看,该有的文件都在。mvn clean compile 也能过。从"代码完整性"的角度看,这个项目没什么问题。
但"能编译通过"和"能跑起来"之间,隔着一条鸿沟。
我缺什么
打开 application-test.yml,逐项对照,才知道自己缺了多少东西:
数据库—最致命的一块
spring:
datasource:
url: jdbc:mysql://localhost:3306/ent_register
username: admin
password: 123456
配置写得清清楚楚:本地MySQL,库名 ent_register,账号admin,密码123456。
但问题是——这个库不存在了。
测试环境的MySQL已经回收,生产库的DDL没有导出过。我手里连一张建表语句都没有。24个Mapper XML对应24张表,每张表的字段、索引、外键关系,全靠猜。
没有数据库,项目启动时第一件事就是连数据源——连不上,直接报错退出。
第一把就死在这。
OSS平台—登录不了
oss:
baseUrl: http://xiaomayi.oss.com/gateway
loginUrl: /sys/login
refreshToken: /sys/refresh_token
backAuthInfo: /api-u/successAuthInfo
这个项目的登录不是自己做的,是调用OSS平台的网关。用户输入账号密码 → 本系统HTTP POST到OSS → OSS返回AES加密的用户信息 → 本系统解密后写Session。
问题是:xiaomayi.oss.com 这个测试环境地址,已经不存在了。域名到期,服务下线。
就算数据库有了,登录也登不了。没有登录,所有需要 @AuthCompany、@AuthDept、@AuthBack 鉴权的接口全部进不去。
华为云OBS—文件功能全废
file:
huaweiyun:
endpoint: https://obs.cn-east.myhuaweicloud.com
accessKeyId: CWHHUIYLX6MAVTXA1WBLKJFVI0
accessKeySecret: iuj1QXzxbet
bucketName: lhrtbp15g
AK/SK写在配置文件里——这本身是个安全问题,但更现实的问题是:这个华为云账号已经不是我的了。
企业营业执照上传、财务报告上传、诊断报告PDF下载——所有文件功能都走华为云OBS。AK/SK失效,这些功能全部报403。
运行环境
<packaging>war</packaging>
<java.version>1.8</java.version>
WAR包部署,需要外置Tomcat。Java版本要求1.8。我现在的开发机是JDK 17,Tomcat也不在了。
小结:缺失清单
| 缺失项 | 影响 | 严重程度 |
|---|---|---|
| OSS测试环境 | 无法登录 | 🔴 致命 |
| 数据库DDL + 数据 | 启动直接失败 | 🔴 致命 |
| 华为云OBS账号 | 文件功能全废 | 🟠 严重 |
| JDK 8 + Tomcat | 运行环境不匹配 | 🟡 中等 |
4项缺失,2项致命,1项严重。这不是"改改配置就能跑"的问题,是整个运行生态都不在了。
我尝试过补救,但都没成功:
- 给前同事发消息要DDL,回复 “那个人离职了,没备份”。
- 尝试逆向工程:24个Mapper XML里有完整的SQL,理论上可以用MyBatis-Plus的
SchemaGenerator反向生成DDL。但这是2022年的项目,用了大量的ResultMap自定义映射,反向生成的DDL和实际运行的表结构大概率不一致。我试了一晚上,放弃了。- 至于OSS测试环境的登录——那彻底无解。域名都到期了,只能把登录放一放。
为什么这些东西会丢?
你可能会问:这些东西怎么会没有?一个正经的项目,不该有这些东西吗?
答案是——在当时看来,每一样缺失都有"合理"的理由。
数据库脚本:谁的事?
建表语句是DBA在Navicat里手动执行的,DDL没走过Flyway或Liquibase。初始化数据(字典表、系统配置)是INSERT语句直接跑的。
DBA觉得:"这是运维的事,生产环境我来管。" 开发觉得:"这是DBA的事,我只管写SQL。" 项目经理觉得:"测试环境的事,上线前再说。"
结果:谁都觉得不是自己的事,数据库脚本就成了"没人管的孩子"。
配置信息:散落在"只有本地有"的地方
-
数据库密码在哪?
IDE的Run Configuration里。
-
测试环境的OSS地址在哪?
application-test.yml里——但这个文件是后补的,一开始是写在本地IDE启动参数里的。
-
RabbitMQ的vhost和密码在哪?
可能是在微信群里运维发的一串文字。
这些东西从来没有进入过版本管理。 它们散落在IDE配置、本地文件、聊天记录、甚至脑子里。人一走,信息就断了。
外部测试环境:"临时"的代价
OSS的测试地址是"临时"申请的。
"临时" 意味着有到期时间。到期了就回收,没人续。项目还在跑,但周围的 "脚手架" 已经拆了。
没有"一键启动"的文档
项目交接时,只交了代码。"你照着application.yml配一下就能跑"——说得轻巧。
光华为云OBS就要:注册华为云账号 → 开通OBS服务 → 创建桶 → 生成AK/SK → 配置域名白名单。这还没算OSS系统的账号申请。
没有一个文档写过"从零到跑起来"的步骤。因为写文档的人觉得"大家都知道",而看文档的人发现"大家都不知道"。
一个项目"可交付"的最低标准
踩完这个坑,我总结了一份清单。以后不管什么项目,交接时按这个清单打勾,少一项都不算"可交付"。
源码层
✅ Git仓库,含完整提交历史
✅ README.md 包含:项目简介、技术栈、启动步骤
✅ pom.xml / build.gradle 能正常编译
数据库层
✅ DDL脚本(建表语句)——必须走版本管理
推荐:Flyway / Liquibase,随代码一起提交
最低要求:mysqldump 导出一份完整的DDL
✅ 初始化数据脚本(字典表、配置表的基础数据)
✅ 测试数据脚本(可选,但有的话新人能直接看到效果)
这是本次项目最致命的缺失。 代码丢了可以重写,数据库丢了就是丢了。
配置层
✅ 所有外部系统的地址、账号、密钥
├── 数据库连接信息
├── 消息队列连接信息
├── 对象存储AK/SK
├── 第三方API地址和密钥
└── 区分 dev / test / prod 三套
✅ 配置管理方式
├── 最低要求:application-{env}.yml 全部进Git(密钥用占位符)
├── 中级方案:环境变量注入 ${OBS_AK}
└── 高级方案:配置中心(Nacos / Apollo)
环境层
✅ 一键启动脚本
├── 最佳方案:docker-compose.yml(MySQL + Redis + RabbitMQ 全包含)
├── 中级方案:Vagrant / Dockerfile
└── 最低要求:README.md 写清楚"装什么、配什么、启动什么"
✅ 运行环境要求
├── JDK版本(如1.8)
├── 应用服务器(如Tomcat 9.x)
└── 本地工具(如wkhtmltopdf的安装路径)
外部依赖层
✅ 外部依赖清单
├── 哪些功能依赖外部系统
├── 每个外部系统的地址、联系人、账号获取方式
└── 没有外部系统时,功能的降级行为是什么
✅ Mock方案
├── 外部API的Mock Server(如WireMock)
└── 或者至少提供一组"可用的测试账号和环境"
账号层
✅ 测试环境登录账号
├── 各角色的测试账号(管理员/企业/职能部门)
└── 短信验证码的绕过方式(如万能验证码)
衡量标准:新人来了,多久能跑起来?
说了这么多,其实判断一个项目成不成熟,就一个标准:
新人来了,从零开始,多久能跑起来?
| 时间 | 评级 | 说明 |
|---|---|---|
| < 30分钟 | ⭐⭐⭐⭐⭐ | docker-compose up -d,搞定 |
| 30分钟 - 2小时 | ⭐⭐⭐⭐ | 照着README装环境、改配置,能跑 |
| 2小时 - 1天 | ⭐⭐⭐ | 需要问老员工几个问题,最终能跑 |
| 1天 - 1周 | ⭐⭐ | 缺东西,要自己搭Mock,勉强能跑部分功能 |
| 永远跑不起来 | ⭐ | 就是我现在这个项目 |
最后一个不是段子,是真实发生的。
老炮点评
老炮语录:
- "代码能编译通过 ≠ 项目能跑起来。" ——编译只是语法检查,跑起来需要整个生态。就像发动机能点火 ≠ 车能上路,你还得有油、有轮子、有驾照。
- "一个项目最值钱的不是代码,是让它跑起来的那套配置和数据。" ——代码丢了可以重写,数据库丢了就是丢了。24张表的DDL,每一张都是业务逻辑的结晶。
- "交接项目只给代码,就像卖车只给方向盘。" ——发动机呢?轮胎呢?油呢?你给我的只是一堆零件里最不值钱的那个。
- "衡量一个项目成熟度的标准:新人来了,多久能跑起来。" ——如果答案是"永远跑不起来",那这个项目从一开始就不是"工程",只是"代码"。区别就在于——工程是可复现的。
写在最后
这篇文章不是要吐槽前公司。每一个缺失项,在当时都有 "合理" 的理由——项目紧、人手少、觉得没必要。但"当时觉得没必要"的事情,在交接那天全变成了"当初怎么没做"。
技术债不可怕,文档缺失才可怕。因为代码可以重构,但丢失的数据库脚本和过期的测试环境,找不回来了。
你好,我是老炮,18年Java老兵。这里记录真实项目里的踩坑与避坑经验。关注我,让你少走弯路。
下篇预告:《2022年的老项目,我花了三天终于跑起来了——数据库脚本补全实录》
上次写了《老项目第一把没跑起来》,后台不少朋友问后来怎么样了。后来我通过逆向过程、AI辅助、补数据库、绕开失效的OSS登录、Mock外部依赖,折腾了三天,项目跑起来了,活了。
下期把这段全过程写出来。如果你也拿到过跑不起来的项目,下期这篇会很有用。
我是老炮,18年Java老兵。这里记录真实项目里的踩坑与避坑经验,关注我,让你少走弯路。