如何阻止FreezingArchRule自动减少已存储违规及解决Jenkins执行报错
问题1:Jenkins单模块构建时ArchTest冻结更新报错的解决办法
报错原因:本地全模块构建时,冻结文件记录了所有模块的违规;但Jenkins仅检出单个模块构建时,ArchTest扫描到的违规远少于冻结文件中的记录,默认配置下不允许修改冻结文件,因此抛出StoreUpdateFailedException。
解决选项:
- 推荐:按模块拆分冻结文件
将ArchTest用例按模块拆分,每个模块的测试仅扫描自身代码,冻结文件(如archunit_冻结规则名.store)也放在对应模块的测试资源目录下。这样单模块构建时,只处理本模块的冻结文件,不会涉及其他模块的违规记录,避免冲突。 - 临时方案:开启冻结文件更新权限
在Jenkins构建的JVM参数中添加-Dfreeze.store.default.allowStoreUpdate=true,允许ArchTest更新冻结文件。但注意:这种方式会让ArchTest认为未被扫描的模块违规已修复,从而从冻结文件中删除,导致后续全模块构建时出现大量新的违规提示,仅适合临时场景。
问题2:阻止FreezingArchRule自动移除已修复的违规
默认情况下,FreezingArchRule会在违规修复后自动从冻结文件中删除对应条目,若要保留这些条目,可通过自定义冻结存储实现:
- 自定义存储类,保留所有历史冻结违规:
import com.tngtech.archunit.lang.ArchConditionViolation; import com.tngtech.archunit.lang.ArchRule; import com.tngtech.archunit.library.freeze.FreezingArchRule; import java.util.HashSet; import java.util.Set; public class PreservingFreezeStore implements FreezingArchRule.Store { private final FreezingArchRule.Store delegate; public PreservingFreezeStore(FreezingArchRule.Store delegate) { this.delegate = delegate; } @Override public Set<ArchConditionViolation> read(ArchRule rule) { return delegate.read(rule); } @Override public void update(ArchRule rule, Set<ArchConditionViolation> currentViolations) { // 读取已有的冻结违规记录 Set<ArchConditionViolation> existingViolations = delegate.read(rule); // 合并现有记录与当前扫描到的新违规,保留所有历史条目 Set<ArchConditionViolation> updatedViolations = new HashSet<>(existingViolations); updatedViolations.addAll(currentViolations); // 执行更新操作 delegate.update(rule, updatedViolations); } }
- 在创建FreezingArchRule时使用该自定义存储:
ArchRule yourRule = classes().that().resideInAPackage("com.your.package").should()....; FreezingArchRule frozenRule = FreezingArchRule.freeze(yourRule) .usingStore(new PreservingFreezeStore(FreezingArchRule.Store.defaultStore()));
也可以选择手动维护冻结文件:关闭自动更新(默认状态),即使违规修复,冻结文件中的条目也不会被删除,但需要手动清理已修复的违规,适合对冻结记录有严格管控的场景。
内容的提问来源于stack exchange,提问作者Codinggeek
相关产品推荐
相关产品推荐

