Java项目Drools打包成Jar后出现NoSuchMethodError问题求助
问题解决:Drools打包成Jar后运行时
kb.buildAll()抛出NoSuchMethodError 问题描述
本地IntelliJ中运行Drools规则构建代码正常,但打包成Jar后执行kb.buildAll()时抛出以下异常:
java.lang.reflect.InvocationTargetException ... Caused by: java.lang.NoSuchMethodError: 'void org.apache.maven.artifact.repository.ArtifactRepository.setMirroredRepositories(java.util.List)'
原因分析
这是Maven依赖版本冲突导致的:
Drools的kie-maven-integration模块依赖特定版本的Maven API,但打包后的Jar中混入了不兼容的低版本Maven依赖(比如maven-artifact),低版本中不存在setMirroredRepositories方法,而Drools运行时调用的高版本Maven bridge模块需要这个方法,最终引发运行时错误。
解决方案
1. 排除冲突的Maven依赖
在pom.xml中给Drools相关依赖添加排除规则,移除不必要的Maven核心依赖:
<dependency> <groupId>org.drools</groupId> <artifactId>drools-compiler</artifactId> <version>你的Drools版本号</version> <exclusions> <exclusion> <groupId>org.apache.maven</groupId> <artifactId>maven-artifact</artifactId> </exclusion> <exclusion> <groupId>org.apache.maven</groupId> <artifactId>maven-core</artifactId> </exclusion> <exclusion> <groupId>org.apache.maven</groupId> <artifactId>maven-builder-support</artifactId> </exclusion> <exclusion> <groupId>org.apache.maven</groupId> <artifactId>maven-repository-metadata</artifactId> </exclusion> </exclusions> </dependency>
2. 检查并清理依赖树
执行以下命令查看项目依赖树,定位引入冲突Maven依赖的来源:
mvn dependency:tree
找到所有org.apache.maven相关的依赖,确认是否有低版本被意外引入,然后在对应的依赖上添加排除规则。
3. 优化打包方式
如果使用Maven Shade插件打包,确保配置中不会包含冲突的Maven依赖,或者添加过滤规则:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <filters> <filter> <artifact>org.apache.maven:*</artifact> <excludes> <exclude>**/*</exclude> </excludes> </filter> </filters> </configuration> </execution> </executions> </plugin>
也可以改用maven-assembly-plugin构建可执行Jar,更精准地控制打包内容。
4. 预编译规则(推荐)
避免在运行时动态构建规则,改用Drools Maven插件在编译阶段预编译规则为KJar,运行时直接加载:
- 在pom.xml中添加Drools编译插件:
<plugin> <groupId>org.drools</groupId> <artifactId>drools-maven-plugin</artifactId> <version>你的Drools版本号</version> <executions> <execution> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin>
- 修改规则加载代码,直接加载预编译的KJar:
public class DroolsBeanFactory { private KieServices kieServices = KieServices.Factory.get(); public KieSession getKieSession(){ KieContainer kContainer = kieServices.newKieClasspathContainer(); return kContainer.newKieSession(); } }
这种方式彻底避免了运行时依赖Maven API,从根源上解决冲突问题。
内容的提问来源于stack exchange,提问作者Piyush Shrivastava
相关产品推荐
相关产品推荐

