使用Drools 7向导决策表执行Kie会话时触发空指针异常
Drools决策表触发NPE问题的排查与解决
我来帮你定位并解决这个Drools决策表引发的空指针异常(NPE)问题。从你的描述来看,普通DRL文件能正常运行,但KIE Workbench生成的决策表打包后就出问题,核心异常是ExceptionInInitializerError,这通常和类加载、类初始化或者规则中的类引用有关。
核心问题分析
ExceptionInInitializerError一般是类的静态代码块执行失败,或者静态变量初始化出错,结合你的场景,大概率是决策表生成的DRL中引用的实体类(InputDTO、CustomerDto)无法被正确加载或初始化,导致规则在初始化阶段抛出异常,进而引发后续的空指针问题。
具体修复步骤
1. 确保类包路径一致
首先检查决策表DRL的package声明和你的实体类实际包路径是否匹配。你的DRL开头是package gr.maven.test.testbuildinmaven;,如果InputDTO或CustomerDto不在这个包下,必须添加显式的导入语句:
package gr.maven.test.testbuildinmaven; // 替换成你实际的包路径 import com.yourpackage.InputDTO; import com.yourpackage.CustomerDto;
如果实体类确实在这个包下,也建议加上导入语句,避免类加载歧义。
2. 检查实体类的无参构造函数
Drools在通过new CustomerDto()实例化对象时,需要类有公共的无参构造函数。如果你的CustomerDto只定义了带参构造,一定要补充无参构造:
public class CustomerDto { // 必须添加无参构造 public CustomerDto() {} // 其他属性和方法 private String customerMessage; // getter和setter }
3. 统一KieSession的类加载器
在REST服务环境中,类加载器隔离很容易导致问题。创建KieContainer时,指定使用当前线程的上下文类加载器,确保规则能加载到应用中的实体类:
KieServices kServices = KieServices.Factory.get(); // 使用上下文类加载器创建容器 KieContainer kContainer = kServices.getKieClasspathContainer(Thread.currentThread().getContextClassLoader()); StatelessKieSession kSession = kContainer.newStatelessKieSession();
4. 验证Jar包完整性
解压你打包的Jar文件,检查以下内容:
- 实体类(
InputDTO.class、CustomerDto.class)是否存在 - 决策表生成的DRL文件是否在正确的包路径下
- 所有依赖的Drools相关类是否被正确打包(如果是fat jar的话)
你的代码与异常信息整理
Java执行代码
public CustomerDto executeStatelessPOC(final String param, final StatelessKieSession kSession ,final KieServices kServices) { // Myexample is just the entry fact InputDTO example = new InputDTO(); example.setField1(param); CustomerDto response = new CustomerDto(); try { KieCommands kieCommands = kServices.getCommands(); List<Command> cmds = new ArrayList<Command>(); cmds.add(kieCommands.newInsert(example)); cmds.add(kieCommands.newInsert(response, "customerResponse")); // Execute rules with facts provided before ExecutionResults results = kSession.execute(kieCommands.newBatchExecution(cmds)); // Get the response as part of the results response = (CustomerDto) results.getValue("customerResponse"); return response; } catch (Exception e) { System.out.println("Exception e: " + e.toString()); System.out.println("Exception e: " + Arrays.toString(e.getStackTrace())); } return response; }
向导决策表生成的DRL源码
package gr.maven.test.testbuildinmaven; // from row number: 1 rule "Row 1 TestDecisionTable" dialect "mvel" when Input : InputDTO( field1 == "Test1" ) then CustomerDto fact0 = new CustomerDto(); fact0.setCustomerMessage( "yesss" ); insertLogical( fact0 ); end // from row number: 2 rule "Row 2 TestDecisionTable" dialect "mvel" when Input : InputDTO( field1 == "Test2" ) then CustomerDto fact0 = new CustomerDto(); fact0.setCustomerMessage( "yes2" ); insertLogical( fact0 ); end // from row number: 3 rule "Row 3 TestDecisionTable" dialect "mvel" when Input : InputDTO( field1 == "Test3" ) then CustomerDto fact0 = new CustomerDto(); fact0.setCustomerMessage( "yesss" ); insertLogical( fact0 ); end
异常信息
WARNING: The following warnings have been detected: WARNING: Unknown HK2 failure detected: MultiException stack 1 of 2 java.lang.ExceptionInInitializerError at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.glassfish.hk2.utilities.reflection.ReflectionHelper.makeMe(ReflectionHelper.java:1129) at org.jvnet.hk2.internal.ClazzCreator.createMe(ClazzCreator.java:274) at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:368) at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471) at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162) at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2064) at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:711) at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:653) at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:169) at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:185) at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74) at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:109) at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112) at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112) at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112) at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112) at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:92) at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:61) at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197) at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:297) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) at org.glassfish.jersey.internal.Errors.process(Errors.java:315) at org.glassfish.jersey.internal.Errors.process(Errors.java:297) at org.glassfish.jersey.internal.Errors.process(Errors.java:267) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:288) at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1110) at org.glassfish.jersey.grizz...
内容的提问来源于stack exchange,提问作者user3572380
相关产品推荐
相关产品推荐

