Note: This bug is displayed in read-only format because the product is no longer active in Red Hat Bugzilla.

Bug 1153852

Summary: BPMS rule doesn't get fired after modification if using function call.
Product: [Retired] JBoss BPMS Platform 6 Reporter: Gary Hu <ghu>
Component: BREAssignee: Mario Fusco <mfusco>
Status: CLOSED EOL QA Contact: Marek Winkler <mwinkler>
Severity: high Docs Contact:
Priority: high    
Version: 6.0.3CC: alazarot, etirelli
Target Milestone: ER3   
Target Release: 6.1.0   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 1175917 (view as bug list) Environment:
Last Closed: 2020-03-27 20:13:55 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1175917    
Attachments:
Description Flags
BZ1153852-reproducer.zip none

Description Gary Hu 2014-10-17 02:22:26 UTC
For a BRMS client application that integrates with Kie API and usage within the client is such that KieRepositoryScanner is registered with KieContainer (with module defined by "LATEST" GAV release id) to periodically check for newer release versions of the KieModule available in remote BRMS  knowledge store (business central), download the newer version and automatically update the existing KieContainer used by the client application.

This works as expected for basic smaller Kie projects consisting of single DRL file containing one or two rules (modifications to LHS rule constraints in new versions of the KieModule were applied automatically when scanner retrieved the new version).

However, after adding several more rules and several functions to the DRL file, the KieRepositoryScanner dynamic update to the client's existing KieContainer sometimes results in the modified rules or the rules calling modified functions to not fire on subsequent KieSessions.

After some diggings, the issue seems to be narrowed down to be related to the functions.

If a rule makes a call to a function then any changes to either the rule or the function will cause the rule to not fire after the kieScanner picks up the modifications.

One other issue is that if you make a change that removes the call to the function from the rule, you get a NPE error with the stack trace:

Exception in thread "Timer-0" java.lang.NullPointerException
	at org.drools.core.reteoo.ReteooBuilder.removeRule(ReteooBuilder.java:156)
	at org.drools.core.reteoo.ReteooRuleBase.removeRule(ReteooRuleBase.java:1415)
	at org.drools.core.reteoo.ReteooRuleBase.removeRule(ReteooRuleBase.java:1406)
	at org.drools.compiler.compiler.PackageBuilder.preProcessRules(PackageBuilder.java:1146)
	at org.drools.compiler.compiler.PackageBuilder.compileRules(PackageBuilder.java:1089)
	at org.drools.compiler.compiler.PackageBuilder.compileAllRules(PackageBuilder.java:973)
	at org.drools.compiler.compiler.CompositeKnowledgeBuilderImpl.buildRules(CompositeKnowledgeBuilderImpl.java:266)
	at org.drools.compiler.compiler.CompositeKnowledgeBuilderImpl.buildPackages(CompositeKnowledgeBuilderImpl.java:98)
	at org.drools.compiler.compiler.CompositeKnowledgeBuilderImpl.build(CompositeKnowledgeBuilderImpl.java:87)
	at org.drools.compiler.kie.builder.impl.KieContainerImpl.rebuildAll(KieContainerImpl.java:302)
	at org.drools.compiler.kie.builder.impl.KieContainerImpl.update(KieContainerImpl.java:178)
	at org.drools.compiler.kie.builder.impl.KieContainerImpl.updateDependencyToVersion(KieContainerImpl.java:114)
	at org.kie.scanner.KieRepositoryScannerImpl.updateKieModule(KieRepositoryScannerImpl.java:231)
	at org.kie.scanner.KieRepositoryScannerImpl.scanNow(KieRepositoryScannerImpl.java:218)
	at org.kie.scanner.KieRepositoryScannerImpl$ScanTask.run(KieRepositoryScannerImpl.java:198)
	at java.util.TimerThread.mainLoop(Timer.java:555)
	at java.util.TimerThread.run(Timer.java:505)


The following is the test rule I'm using to show the issues.

package org.drools.examples.shopping

import java.lang.Number;
import java.lang.String;

function boolean doSomething(String name) {
    System.out.println("Function Called ZZZZZ");
    return true ;
}
 
rule "SecondRule" no-loop
dialect "java"
when
	$s : String( )
	eval(doSomething($s))
then
	System.out.println("Firing Second Rule XXX " + $s);
end


The first time after the rule gets compiled and kjar gets installed in local maven repo(or uploaded to business central) everything works fine.

When the BRMS client application keeps running and a change is made over the rule and a new kjar gets built, for example,
 change
    System.out.println("Firing Second Rule XXX " + $s);
 to 
    System.out.println("Firing Second Rule XXXxxx " + $s);
after the kjar is installed in local maven repo(do "vn clean install" against the kjar project), this rule stop firing any more.

If a change is made to remove the function call from the rule, for example, 
change 
     eval(doSomething($s))
to
     //eval(doSomething($s))
after the kjar is installed in maven repo, the NPE error I mentioned above is thrown.

Comment 1 Gary Hu 2014-10-17 02:26:32 UTC
Created attachment 947771 [details]
BZ1153852-reproducer.zip

Comment 3 Gary Hu 2014-10-17 02:40:38 UTC
I've attached a reproducer that could demonstrate the issue.

The reproducer zip file contains two maven projects bpms.test.01256902.sample.kjar and bpms.test.01256902.

The first one is to build the kjar and second one is the test client which uses junit.

Steps to reproduce the issue:

1) unzip the reproduce and go to project bpms.test.01256902.sample.kjar, run command 
     mvn clean install
This should install the kjar in your local maven repo.

2) go to project bpms.test.01256902 and run command
    mvn clean package 
or 
    mvn clean test
This should build the test client and start the junit test. 
From console you should see some printouts that shows something like:
   Firing Second Rule XXX 0
   Firing Second Rule XXX 1
   Firing Second Rule XXX 2
   Firing Second Rule XXX 3
   Firing Second Rule XXX 4

This shows the rule "SecondRule" gets fired without issue.

3) keep the test client running, and make a change to the "SecondRule". 
for example:
  change
    System.out.println("Firing Second Rule XXX " + $s);
  to 
    System.out.println("Firing Second Rule XXXxxx " + $s);

and run command
   mvn clean install

After the maven command finish successfully, you can see the rule stop firing. It doesn't show on the console any more.

4) make further change, say, removing the function call from the rule.
   for example,
       change 
           eval(doSomething($s))
       to
           //eval(doSomething($s))
and run command
   mvn clean install
After it finishes successfully, you should see NPE error:

Exception in thread "Timer-0" java.lang.NullPointerException
	at org.drools.core.reteoo.ReteooBuilder.removeRule(ReteooBuilder.java:156)
	at org.drools.core.reteoo.ReteooRuleBase.removeRule(ReteooRuleBase.java:1415)
	at org.drools.core.reteoo.ReteooRuleBase.removeRule(ReteooRuleBase.java:1406)
	at org.drools.compiler.compiler.PackageBuilder.preProcessRules(PackageBuilder.java:1146)
	at org.drools.compiler.compiler.PackageBuilder.compileRules(PackageBuilder.java:1089)
	at org.drools.compiler.compiler.PackageBuilder.compileAllRules(PackageBuilder.java:973)
	at org.drools.compiler.compiler.CompositeKnowledgeBuilderImpl.buildRules(CompositeKnowledgeBuilderImpl.java:266)
	at org.drools.compiler.compiler.CompositeKnowledgeBuilderImpl.buildPackages(CompositeKnowledgeBuilderImpl.java:98)
	at org.drools.compiler.compiler.CompositeKnowledgeBuilderImpl.build(CompositeKnowledgeBuilderImpl.java:87)
	at org.drools.compiler.kie.builder.impl.KieContainerImpl.rebuildAll(KieContainerImpl.java:302)
	at org.drools.compiler.kie.builder.impl.KieContainerImpl.update(KieContainerImpl.java:178)
	at org.drools.compiler.kie.builder.impl.KieContainerImpl.updateDependencyToVersion(KieContainerImpl.java:114)
	at org.kie.scanner.KieRepositoryScannerImpl.updateKieModule(KieRepositoryScannerImpl.java:231)
	at org.kie.scanner.KieRepositoryScannerImpl.scanNow(KieRepositoryScannerImpl.java:218)
	at org.kie.scanner.KieRepositoryScannerImpl$ScanTask.run(KieRepositoryScannerImpl.java:198)
	at java.util.TimerThread.mainLoop(Timer.java:555)
	at java.util.TimerThread.run(Timer.java:505)

Comment 4 Mario Fusco 2014-10-17 17:17:10 UTC
I couldn't reproduce any NPE on master. Nevertheless using the attached reproducer I found that incremental compilation doesn't work correctly when a rule uses a function. 

I fixed this problem with this commit: https://github.com/droolsjbpm/drools/commit/d905672bf

I also checked 6.0.x branch and found that it suffers of exactly the same problem I found on master. Moreover the fix I pushed on master also solved this issue on 6.0.x

Comment 5 Mario Fusco 2014-10-17 17:41:18 UTC
Backported to 6.0.x with https://github.com/droolsjbpm/drools/commit/f044ef89c

Comment 6 Gary Hu 2014-10-20 13:56:11 UTC
Hi Mario,

I've created a "patch" for BPMS 6.0.3 based on your fix in https://github.com/droolsjbpm/drools/commit/f044ef89c. 

After some more tests, we can verify that it fixes the following scenarios: 

1) A new version of the kjar includes a modification to a rule that calls an existing function
2) A new version of the kjar includes the removal of a function entirely from the DRL and modifications to any rules that previously called removed function.

However, the patched jar does not fix the following kie module update scenario: 

3) A new version of the kjar includes the addition of a new function to the DRL file as well as a modification to a rule in the same DRL to call the new function.

Are you able to look into the issue again to see if we can get the 3) issue fixed?

Comment 7 Gary Hu 2014-10-20 14:22:58 UTC
I just tested the scenario 3) mentioned in your previous post:

3) A new version of the kjar includes the addition of a new function to the DRL file as well as a modification to a rule in the same DRL to call the new function.


I added one new function in the test drl rule. 
for example:
   function boolean doSomething2(String name) {
    System.out.println("Function Called YYYYY");
    return true ;
   }

And I changed the rule
 from
    System.out.println("Firing Second Rule XXX " + $s);
 to
    System.out.println("Firing Second Rule XXXxxx " + $s);


What happened in my test is that I received the following error:

Exception in thread "Timer-0" java.lang.NoSuchMethodError: org.drools.core.reteoo.ReteooRuleBase.removeObjectsGeneratedFromResource(Lorg/kie/api/io/Resource;)Z
	at org.drools.compiler.compiler.PackageBuilder.removeObjectsGeneratedFromResource(PackageBuilder.java:4181)
	at org.drools.compiler.kie.builder.impl.KieContainerImpl.updateResourcesIncrementally(KieContainerImpl.java:260)
	at org.drools.compiler.kie.builder.impl.KieContainerImpl.update(KieContainerImpl.java:161)
	at org.drools.compiler.kie.builder.impl.KieContainerImpl.updateDependencyToVersion(KieContainerImpl.java:114)
	at org.kie.scanner.KieRepositoryScannerImpl.updateKieModule(KieRepositoryScannerImpl.java:231)
	at org.kie.scanner.KieRepositoryScannerImpl.scanNow(KieRepositoryScannerImpl.java:218)
	at org.kie.scanner.KieRepositoryScannerImpl$ScanTask.run(KieRepositoryScannerImpl.java:198)
	at java.util.TimerThread.mainLoop(Timer.java:555)
	at java.util.TimerThread.run(Timer.java:505)


In the meanwhile, the client application continue to fire the old rule. Any changes to the rule are not applied.

Comment 8 Mario Fusco 2014-10-20 16:10:11 UTC
I also fixed scenario 3) with this commit on master https://github.com/droolsjbpm/drools/commit/e4b1bff10 and backported the fix on 6.0.x branch https://github.com/droolsjbpm/drools/commit/dd4901a29

Comment 9 Marek Winkler 2014-12-16 15:15:36 UTC
Verified on BRMS 6.1.0 ER3.

I have encountered unexpected behaviour with LATEST versions - it has been filed as BZ 1174836.