2022年的Java老项目,代码完整却跑不起来——4个致命缺失与避坑清单

14 阅读10分钟

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,勉强能跑部分功能
永远跑不起来⭐就是我现在这个项目

最后一个不是段子,是真实发生的。

老炮点评

老炮语录:

  1. "代码能编译通过 ≠ 项目能跑起来。" ——编译只是语法检查,跑起来需要整个生态。就像发动机能点火 ≠ 车能上路,你还得有油、有轮子、有驾照。
  2. "一个项目最值钱的不是代码,是让它跑起来的那套配置和数据。" ——代码丢了可以重写,数据库丢了就是丢了。24张表的DDL,每一张都是业务逻辑的结晶。
  3. "交接项目只给代码,就像卖车只给方向盘。" ——发动机呢?轮胎呢?油呢?你给我的只是一堆零件里最不值钱的那个。
  4. "衡量一个项目成熟度的标准:新人来了,多久能跑起来。" ——如果答案是"永远跑不起来",那这个项目从一开始就不是"工程",只是"代码"。区别就在于——工程是可复现的。

写在最后

这篇文章不是要吐槽前公司。每一个缺失项,在当时都有 "合理" 的理由——项目紧、人手少、觉得没必要。但"当时觉得没必要"的事情,在交接那天全变成了"当初怎么没做"。

技术债不可怕,文档缺失才可怕。因为代码可以重构,但丢失的数据库脚本和过期的测试环境,找不回来了。

你好,我是老炮,18年Java老兵。这里记录真实项目里的踩坑与避坑经验。关注我,让你少走弯路。

下篇预告:《2022年的老项目,我花了三天终于跑起来了——数据库脚本补全实录》

上次写了《老项目第一把没跑起来》,后台不少朋友问后来怎么样了。后来我通过逆向过程、AI辅助、补数据库、绕开失效的OSS登录、Mock外部依赖,折腾了三天,项目跑起来了,活了。

下期把这段全过程写出来。如果你也拿到过跑不起来的项目,下期这篇会很有用。

我是老炮,18年Java老兵。这里记录真实项目里的踩坑与避坑经验,关注我,让你少走弯路。