DOM解析XML时NodeList.getLength()偶发NullPointerException问题求助
问题根因
- 核心原因是DOM解析相关实现类均非线程安全:
DocumentBuilder、Document、NodeList都没有做线程同步处理,你将解析逻辑放在服务控制器中,而服务控制器默认是单例模式,多请求并发调用时,多个线程同时操作同一个DOM实例会打乱DOM树内部节点状态,遍历NodeList时就会触发该空指针异常。这也是为什么问题是偶发的:只有并发场景下才会触发,单线程场景下运行完全正常。 - 次要可能原因:待解析的XML文件存在被其他进程/线程并发修改的情况,解析时读取到了不完整的XML内容,也可能导致该异常。
修复方案
- 所有DOM相关对象均使用方法局部变量:不要将
DocumentBuilderFactory、DocumentBuilder、Document、NodeList定义为类成员变量,每次执行解析逻辑时都创建独立的实例,确保不同线程的解析操作完全隔离,不会互相干扰。
- 所有DOM相关对象均使用方法局部变量:不要将
- 增加文件读取保护:如果该XML文件存在动态更新的场景,读取解析前加文件锁,确保读取到的是完整的XML内容后再执行解析。
- 增加代码健壮性校验:获取NodeList后先做非空判断,再执行遍历逻辑,避免异常直接抛出:
NodeList nList = doc.getElementsByTagName("problem"); if (nList != null) { for (int temp = 0; temp < nList.getLength(); temp++) { // 执行业务逻辑 } }
- 高并发场景可替换解析方式:如果服务并发量较高,可换用StAX流式解析,相比DOM解析内存占用更低,并发场景下稳定性更好。
内容的提问来源于stack exchange,提问作者anmi
相关产品推荐
相关产品推荐

