DefaultKnowledgeHelper.java:357 中的 NullPointerException

NullPointerException in DefaultKnowledgeHelper.java:357

在 Drools 中获取 NPE 似乎是 known issue
我正在使用 drools 5.5.0.final。需要一些解决方法。

    ==> 'node heart beat arrival timeout' has been activated by the tuple [null]
    21:16:15,150  WARN DefaultTimerJobInstance:63 - Unable to execute timer job!
    Exception executing consequence for rule "node heart beat arrival timeout" in my.secret.company.mmc.cep: java.lang.NullPointerException
        at org.drools.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:39)
        at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1297)
        at org.drools.common.DefaultAgenda.fireTimedActivation(DefaultAgenda.java:1344)
        at org.drools.common.Scheduler$ActivationTimerJob.execute(Scheduler.java:83)
        at org.drools.time.SelfRemovalJob.execute(SelfRemovalJob.java:15)
        at org.drools.time.impl.DefaultTimerJobInstance.call(DefaultTimerJobInstance.java:51)
        at org.drools.time.impl.DefaultTimerJobInstance.call(DefaultTimerJobInstance.java:14)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:178)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: java.lang.NullPointerException
        at org.drools.base.DefaultKnowledgeHelper.retract(DefaultKnowledgeHelper.java:357)
        at my.secret.company.mmc.cep.Rule_node_heart_beat_arrival_timeout_a41bd73ea00c4975b04415e563fb3e62.defaultConsequence(Rule_node_heart_beat_arrival_timeout_a41bd73ea00c4975b04415e563fb3e62.java:9)
        at my.secret.company.mmc.cep.Rule_node_heart_beat_arrival_timeout_a41bd73ea00c4975b04415e563fb3e62DefaultConsequenceInvokerGenerated.evaluate(Unknown Source)
        at my.secret.company.mmc.cep.Rule_node_heart_beat_arrival_timeout_a41bd73ea00c4975b04415e563fb3e62DefaultConsequenceInvoker.evaluate(Unknown Source)
        at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1287)
        ... 11 more

    ==> 'node heart beat received' has been activated by the tuple [null, null]
    Exception executing consequence for rule "node heart beat received" in my.secret.company.mmc.cep: java.lang.NullPointerException
        at org.drools.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:39)
        at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1297)
        at org.drools.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:1221)
        at org.drools.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1456)
        at org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:710)
        at org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:674)
        at org.drools.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:230)
        at my.secret.company.cep.DroolsAssert.fireAllRules(DroolsAssert.java:302)
        at my.secret.company.cep.DroolsAssert.insertAndFire(DroolsAssert.java:309)
        at my.secret.company.mmc.cep.SuperCepRulesTest.run(SuperCepRulesTest.java:272)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: java.lang.NullPointerException
        at org.drools.base.DefaultKnowledgeHelper.retract(DefaultKnowledgeHelper.java:357)
        at my.secret.company.mmc.cep.Rule_node_heart_beat_received_7df7ea24b0c74c25b8b0b86f4a8b1b1d.defaultConsequence(Rule_node_heart_beat_received_7df7ea24b0c74c25b8b0b86f4a8b1b1d.java:7)
        at my.secret.company.mmc.cep.Rule_node_heart_beat_received_7df7ea24b0c74c25b8b0b86f4a8b1b1dDefaultConsequenceInvokerGenerated.evaluate(Unknown Source)
        at my.secret.company.mmc.cep.Rule_node_heart_beat_received_7df7ea24b0c74c25b8b0b86f4a8b1b1dDefaultConsequenceInvoker.evaluate(Unknown Source)
        at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1287)
        ... 13 more

这是用例:
1.有相同tuples/objects
触发的乘法规则 2. 一条规则 retracted/invalidated 触发它的对象。
3. 另一个规则已经安排好了,对变化一无所知。
它在 DefaultKnowledgeHelper.retract(DefaultKnowledgeHelper.java:357) 处出现 NullPointerException,因为 handle.getEntryPoint() == null(无效)

5.5 的内联修复。0.final(应该进行适当的 API 更改以使逻辑清晰)。

DefaultFactHandle.java

    -    private int                     id;
    +    private volatile int                     id;

DefaultAgenda.java(fireActivation 方法)

    -        try {
    -            increaseDormantActivations();
    -            decreaseActiveActivations();
    +        try {
    +            increaseDormantActivations();
    +            decreaseActiveActivations();
    +            
    +            for (FactHandle factHandle : activation.getFactHandles())
    +                if (!((InternalFactHandle) factHandle).isValid())
    +                    return;

以下是需要考虑的其他堆栈跟踪:

    Thread [pool-1-thread-1] (Suspended (modification of field entryPoint in DefaultFactHandle))    
        owns: DefaultAgenda  (id=27071) 
        EventFactHandle(DefaultFactHandle).invalidate() line: 232   
        ReteooFactHandleFactory(AbstractFactHandleFactory).destroyFactHandle(InternalFactHandle) line: 94   
        NamedEntryPoint.retract(FactHandle, boolean, boolean, Rule, Activation) line: 606   
        DefaultKnowledgeHelper.retract(FactHandle) line: 357    
        Rule_node_heart_beat_arrival_timeout_a8e57af87b4c49aabea42ea1015155d4.defaultConsequence(KnowledgeHelper, EventImpl, FactHandle, ProducerTemplate) line: 9  
        Rule_node_heart_beat_arrival_timeout_a8e57af87b4c49aabea42ea1015155d4DefaultConsequenceInvokerGenerated.evaluate(KnowledgeHelper, WorkingMemory) line: not available    
        Rule_node_heart_beat_arrival_timeout_a8e57af87b4c49aabea42ea1015155d4DefaultConsequenceInvoker.evaluate(KnowledgeHelper, WorkingMemory) line: not available 
        DefaultAgenda.fireActivation(Activation) line: 1287 
        DefaultAgenda.fireTimedActivation(Activation, boolean) line: 1344   
        Scheduler$ActivationTimerJob.execute(JobContext) line: 83   
        SelfRemovalJob.execute(JobContext) line: 15 
        DefaultTimerJobInstance.call() line: 51 
        DefaultTimerJobInstance.call() line: 14 
        ScheduledThreadPoolExecutor$ScheduledFutureTask<V>(FutureTask<V>).run() line: 262   
        ScheduledThreadPoolExecutor$ScheduledFutureTask<V>.access1(ScheduledThreadPoolExecutor$ScheduledFutureTask) line: 178    
        ScheduledThreadPoolExecutor$ScheduledFutureTask<V>.run() line: 292  
        ScheduledThreadPoolExecutor(ThreadPoolExecutor).runWorker(ThreadPoolExecutor$Worker) line: 1145 
        ThreadPoolExecutor$Worker.run() line: 615   
        Thread.run() line: 745  

    ==> 'node heart beat arrival timeout' has been activated by the tuple [null]
    21:16:15,150  WARN DefaultTimerJobInstance:63 - Unable to execute timer job!
    Exception executing consequence for rule "node heart beat arrival timeout" in my.secret.company.mmc.cep: java.lang.NullPointerException
        at org.drools.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:39)
        at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1297)
        at org.drools.common.DefaultAgenda.fireTimedActivation(DefaultAgenda.java:1344)
        at org.drools.common.Scheduler$ActivationTimerJob.execute(Scheduler.java:83)
        at org.drools.time.SelfRemovalJob.execute(SelfRemovalJob.java:15)
        at org.drools.time.impl.DefaultTimerJobInstance.call(DefaultTimerJobInstance.java:51)
        at org.drools.time.impl.DefaultTimerJobInstance.call(DefaultTimerJobInstance.java:14)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:178)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: java.lang.NullPointerException
        at org.drools.base.DefaultKnowledgeHelper.retract(DefaultKnowledgeHelper.java:357)
        at my.secret.company.mmc.cep.Rule_node_heart_beat_arrival_timeout_a41bd73ea00c4975b04415e563fb3e62.defaultConsequence(Rule_node_heart_beat_arrival_timeout_a41bd73ea00c4975b04415e563fb3e62.java:9)
        at my.secret.company.mmc.cep.Rule_node_heart_beat_arrival_timeout_a41bd73ea00c4975b04415e563fb3e62DefaultConsequenceInvokerGenerated.evaluate(Unknown Source)
        at my.secret.company.mmc.cep.Rule_node_heart_beat_arrival_timeout_a41bd73ea00c4975b04415e563fb3e62DefaultConsequenceInvoker.evaluate(Unknown Source)
        at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1287)
        ... 11 more

    ==> 'node heart beat received' has been activated by the tuple [null, null]
    Exception executing consequence for rule "node heart beat received" in my.secret.company.mmc.cep: java.lang.NullPointerException
        at org.drools.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:39)
        at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1297)
        at org.drools.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:1221)
        at org.drools.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1456)
        at org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:710)
        at org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:674)
        at org.drools.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:230)
        at my.secret.company.cep.DroolsAssert.fireAllRules(DroolsAssert.java:302)
        at my.secret.company.cep.DroolsAssert.insertAndFire(DroolsAssert.java:309)
        at my.secret.company.mmc.cep.SuperCepRulesTest.run(SuperCepRulesTest.java:272)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: java.lang.NullPointerException
        at org.drools.base.DefaultKnowledgeHelper.retract(DefaultKnowledgeHelper.java:357)
        at my.secret.company.mmc.cep.Rule_node_heart_beat_received_7df7ea24b0c74c25b8b0b86f4a8b1b1d.defaultConsequence(Rule_node_heart_beat_received_7df7ea24b0c74c25b8b0b86f4a8b1b1d.java:7)
        at my.secret.company.mmc.cep.Rule_node_heart_beat_received_7df7ea24b0c74c25b8b0b86f4a8b1b1dDefaultConsequenceInvokerGenerated.evaluate(Unknown Source)
        at my.secret.company.mmc.cep.Rule_node_heart_beat_received_7df7ea24b0c74c25b8b0b86f4a8b1b1dDefaultConsequenceInvoker.evaluate(Unknown Source)
        at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1287)
        ... 13 more