Java 21下使用Maven exec插件调用XPathFactory.newInstance()报错求助
问题重现
使用Maven exec插件执行自定义代码生成,配置如下:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.1</version> <executions> <execution> <phase>generate-sources</phase> <goals> <goal>java</goal> </goals> </execution> </executions> <configuration> <includeProjectDependencies>true</includeProjectDependencies> <mainClass>a.b.GenerateClasses</mainClass> <arguments> <argument>${project.basedir}/src/main/wsdl</argument> <argument>-output</argument> <argument>${project.build.directory}/generated-sources/wsdl</argument> </arguments> </configuration> </plugin>
执行时触发错误:
java.lang.RuntimeException: XPathFactory#newInstance() failed to create an XPathFactory for the default object model:
http://java.sun.com/jaxp/xpath/domwith the XPathFactoryConfigurationException: javax.xml.xpath.XPathFactoryConfigurationException: No XPathFactory implementation found for the object model:http://java.sun.com/jaxp/xpath/dom
解决思路
1. 升级Exec Maven插件版本
当前使用的3.1.1版本对Java 11+的模块化支持不完善,升级到最新稳定版(如3.2.0及以上),新版本优化了Java 9+环境下的类路径/模块路径处理逻辑,能自动适配JDK自带的XML相关实现:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.2.0</version> <!-- 其余配置保持不变 --> </plugin>
2. 显式指定XPathFactory实现类
在插件配置中添加系统属性,强制指定JDK自带的XPathFactory实现,绕过自动发现机制的问题:
<configuration> <includeProjectDependencies>true</includeProjectDependencies> <mainClass>a.b.GenerateClasses</mainClass> <systemProperties> <property> <name>javax.xml.xpath.XPathFactory:http://java.sun.com/jaxp/xpath/dom</name> <value>com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl</value> </property> </systemProperties> <arguments> <argument>${project.basedir}/src/main/wsdl</argument> <argument>-output</argument> <argument>${project.build.directory}/generated-sources/wsdl</argument> </arguments> </configuration>
3. 调整模块化配置(若项目为模块化项目)
如果你的项目使用module-info.java,需显式声明对java.xml模块的依赖,确保模块系统能加载XPath相关实现:
module your.module.name { requires java.xml; // 其他模块依赖... }
4. 强制使用类路径加载(临时兼容方案)
在插件配置中关闭模块路径使用,强制采用传统类路径加载方式,避免模块化机制的影响:
<configuration> <includeProjectDependencies>true</includeProjectDependencies> <mainClass>a.b.GenerateClasses</mainClass> <useModulePath>false</useModulePath> <!-- 其余配置保持不变 --> </configuration>
验证顺序
优先尝试升级插件版本,这是最稳妥的长期解决方案;若升级后问题仍存在,再依次尝试指定系统属性、调整模块配置或关闭模块路径。
内容的提问来源于stack exchange,提问作者lhahne

