jQAssistant Maven插件对非空Neo4j库扫描失败是什么原因?
问题原因与解决方案
根因分析
- 首次扫描时Neo4j数据库为空,jQAssistant执行的内部查询未触发异常场景,所以运行正常。增量扫描时数据库已存在历史扫描生成的代码结构节点与关联关系,jQAssistant内置或用户自定义的规则中用到
shortestPath最短路径查询的语句,在部分查询行匹配到起止节点为同一节点的场景,触发了Neo4j默认开启的cypher.forbid_shortestpath_common_nodes配置校验,直接抛出致命错误终止当前事务。 - 事务被终止后,后续所有类扫描、节点属性更新的数据库操作都无法执行,因此会接连出现类扫描失败、语句无法执行的连锁报错。
解决方案
临时快速修复
直接修改Neo4j配置文件neo4j.conf,添加如下配置:
cypher.forbid_shortestpath_common_nodes=false
重启Neo4j服务后重新执行扫描即可。该方案无需调整jQAssistant的规则或版本,适合对依赖分析结果完整性要求不高的场景,缺点是会自动忽略所有起止节点相同的最短路径查询结果。
永久彻底修复
如果不能接受查询结果遗漏,可按照如下步骤处理:
- 升级jQAssistant到最新稳定版,旧版本的内置扫描规则存在未对
shortestPath查询的起止节点做一致性校验的缺陷,新版本官方已经修复了该问题。 - 如果存在自定义的Cypher扫描/校验规则,需要对用到
shortestPath的语句做改造:- 增加节点校验条件,提前过滤掉起止节点相同的行:
MATCH (a:Class), (b:Class) // 新增过滤条件,避免匹配到同一节点 WHERE id(a) <> id(b) MATCH p = shortestPath((a)-[DEPENDS_ON*]-(b)) RETURN p - 或者替换
shortestPath函数为可变长度路径匹配,手动取最短路径:MATCH (a:Class), (b:Class) WHERE id(a) <> id(b) MATCH p = (a)-[DEPENDS_ON*]-(b) RETURN p ORDER BY length(p) ASC LIMIT 1
- 增加节点校验条件,提前过滤掉起止节点相同的行:
内容的提问来源于stack exchange,提问作者eerriicc
相关产品推荐
相关产品推荐

