使用Transformer和PowerMockRunner时出现属性文件加载异常求助
问题描述
需要将Document对象转换为String类型,当前使用的实现方法如下:
public static String toString(Document doc) { try { TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); StringWriter sw = new StringWriter(); transformer.transform(new DOMSource(doc), new StreamResult(sw)); String writerAsString = sw.toString(); return writerAsString; } catch (Exception ex) { throw new RuntimeException("Error converting to String", ex); } }
上述代码常规运行时可正常执行,但在运行单元测试、添加@RunWith(PowerMockRunner.class)注解时,会抛出如下错误:
Caused by: com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException: Could not load the propery file 'output_xml.properties' for output method 'xml' (check CLASSPATH)
问题原因
这个问题是PowerMock的类加载机制导致的:
PowerMock运行时会使用自定义的Mock类加载器加载测试关联的类,默认会接管JDK内置XML组件的类加载逻辑,但没有正确处理com.sun.org.apache.xml.internal.serializer包下资源文件的加载路径,导致该包下的output_xml.properties配置文件无法被正常检索到,最终抛出类路径资源找不到的异常。
解决方案
优先选择改动最小的方案1即可:
- 方案1:在使用PowerMockRunner的单元测试类上添加
@PowerMockIgnore注解,指定XML相关的包由系统类加载器加载,避开PowerMock类加载器的干扰,注解配置如下:
加完该注解后,JDK内置的XML转换器就能正常加载所需的配置文件,异常会直接消失。@PowerMockIgnore({ "javax.xml.*", "org.xml.sax.*", "com.sun.org.apache.xalan.*", "com.sun.org.apache.xml.*" }) - 方案2:不依赖JDK内置的Transformer实现,引入第三方XML处理依赖(比如Xalan、Dom4j),显式指定TransformerFactory的实现类,不走SPI自动加载逻辑,避免被PowerMock拦截类加载过程。
- 方案3:如果使用JDK9及以上版本,可以在测试的JVM启动参数中添加XML模块的强制导出配置,但是该方案需要修改测试启动参数,维护成本更高,不推荐优先使用。
内容的提问来源于stack exchange,提问作者nufar
相关产品推荐
相关产品推荐

