诡异的项目开发时热加载丢失编译的类文件问题

2021-01-10 22:51:25 +08:00
 abcbuzhiming
我们的项目组使用了 spring-boot-devtools,开发 IDE 是 IDEA 的社区版,社区版并不具备商业版的自动 update 热加载方案。所以我们以前的工作流是:修改某个 class——保存——选菜单,build——build 这个 class,因为 build 过程中会触发 class 文件更新被 spring-boot-devtools 捕捉到,就会完成热加载过程。这个方案一直工作的很好。

知道今天同事反映,有一个模块 A,有些奇怪,修改了 Controller,触发热重载,然后这个 Controller 下的所有 api 路径全部就 404 了,只能停止并重启才能正常。我很奇怪于是研究了一下,发现是这个被修改的 Controller 并没有在热重载时被载入,也就是这个 class“被丢失了”。进一步发现这个问题在所有人的 IDE 上都会复现,每次都一定出现。

我就觉得很奇怪了,首先去网上搜索了一下方案,发现 spring 提到了两个变量
spring.devtools.restart.poll-interval
spring.devtools.restart.quiet-period

前者是 spring devtools 多久去检测一次 class 变动,后者是 devtools 缄默间隔时间。网上有个解释,说,如果你编译时间太长,超过了 devtools 的检测时间,就会导致 devtools 认为你这个 class 被删除了,所以不会重新载入。

我尝试拉长第一个选项到 3 秒,确实能解决这个问题。

但是很奇怪,因为这个项目不止这个模块,其它模块可没有设置这个选项啊,为啥其它模块没有这个问题?

然后我开始了漫长的对比测试,最终发现,出问题的这个模块 A,执行 build——build class 这个过程中,所花费的时间,和别的模块没有区别,但是离谱的是,从日志滚动可以看出,A 模块的 spring-boot-devtools 比其它模块,更早的开始执行热重载(日志开始有动作的时间点)。这一点是导致 A 模块丢失编译的类文件的核心问题。

我做了很多测试,包含把上面两个配置给 A 模块和其它模块都配上,而且都设置为系统默认的时长,poll-interval 为 1000ms,quiet-period 为 400ms 。但是没用,A 模块每次都会更早的(编译进度条还没跑完)热重载。实在想不通这是哪个环节造成的问题。

A 模块和其它模块都在一个项目下面,执行他们的时候都在同一个 IDEA,应该可以排除 IDE 问题,我看了一下 IDE 生成的 IML 文件,也没发现异常。

实在没有思路了,请高人赐教
1472 次点击
所在节点    Java
3 条回复
micean
2021-01-10 22:54:01 +08:00
之前我遇到过 recompile 导致 target 里的相应文件丢失的情况,具体怎么解决的倒是忘记了。。。。清下 idea 缓存试试?
abcbuzhiming
2021-01-10 23:10:18 +08:00
@micean 我这个,文件并没有丢失,我去看过,文件还在,但是 spring-boot-devtools 提前加载导致它“错误”了这个 class
kingfalse
2021-01-11 08:47:46 +08:00
裤子还没脱就拉了呗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/743638

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX