使用SAXParser解析XML时随机出现FileNotFoundException问题求助
问题分析与解决方案
首要修复:SAXParserFactory配置顺序错误
你当前禁用外部DTD的代码完全无效——必须先完成factory的所有配置,再创建SAXParser实例,而你现在是先创建parser再设置factory属性,后续配置根本不会生效。
错误代码:
SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); // 错误:先创建parser,配置无法生效 factory.setValidating(false); factory.setNamespaceAware(false); factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
修正后的代码:
SAXParserFactory factory = SAXParserFactory.newInstance(); // 先配置所有属性与特性 factory.setValidating(false); factory.setNamespaceAware(false); try { factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); // 配置完成后再创建Parser SAXParser parser = factory.newSAXParser(); // 执行XML解析逻辑 } catch (ParserConfigurationException | SAXException e) { // 处理配置/解析异常 }
其他排查方向
- 并发资源冲突:如果是多线程环境,检查是否有其他线程随机修改/删除目标文件或目录结构。Linux文件系统的操作原子性与Windows不同,这类问题更容易暴露。
- 共享存储稳定性:使用Samba共享目录时,网络波动可能导致临时文件不可访问。建议在解析前增加重试校验:
File xmlFile = new File("目标文件路径"); int retryTimes = 3; while (retryTimes > 0) { if (xmlFile.exists() && xmlFile.canRead()) { break; } retryTimes--; try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException("等待文件可用时被中断", e); } } if (retryTimes == 0) { throw new FileNotFoundException("重试3次后仍无法访问文件:" + xmlFile.getAbsolutePath()); } // 执行解析
- 路径隐性问题:检查文件路径是否包含Linux敏感的特殊字符(空格、不可见字符),或存在大小写不一致(Linux文件名大小写敏感,Windows不敏感,跨环境部署易出现随机匹配失败)。
- JRE版本升级:你使用的Temurin 17.0.2存在部分XML解析相关已知bug,建议升级到17系列最新稳定版(如17.0.11+9)修复潜在问题。
堆栈信息解读
从堆栈来看,异常触发于XMLEntityManager.setupCurrentEntity阶段,结合配置错误,大概率是XML中存在外部DTD/实体引用,SAXParser尝试加载但因路径或存储问题找不到文件。修正factory配置顺序后,禁用外部DTD加载即可避免这类实体加载引发的异常。
内容的提问来源于stack exchange,提问作者extremecoder85
相关产品推荐
相关产品推荐

