Uploaded image for project: 'Drools'
  1. Drools
  2. DROOLS-4967

decision table rules are not loaded into kiebase

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Blocker Blocker
    • None
    • 7.21.0.Final, 7.22.0.Final, 7.23.0.Final, 7.24.0.Final, 7.25.0.Final, 7.26.0.Final, 7.27.0.Final, 7.28.0.Final, 7.29.0.Final, 7.30.0.Final, 7.31.0.Final
    • decision tables
    • None
    • 2020 Week 07-09 (from Feb 10)
    • Hide

      To reproduce easily, we can use an existing test and a modified xls file. I have used today's master branch of the drools project (7.33.0-SNAPSHOT). It should be reproducible since 7.21.Final, where both the bug and the test were introduced.

      Creating the "bad" xls

      1. in project drools-decisiontables, find this file drools-decisiontables\src\test\resources\org\drools\decisiontable\project\dtable\CanDrink.xls
      2. open a spreadsheet editor (I have used Excel for Office 365, but any should do)
      3. create a new xls file and save it
      4. parallel next to it, open the CanDrink.xls
      5. copy the whole column A from CanDrink.xls to the other file and save it
      6. copy the whole column B from CanDrink.xls to the other file and save it

      We now have two xls files which seem identical in their content.

      Running the test
      We're gonna use the org.drools.decisiontable.project.MultiKieBaseTest tests

      1. run the test, ensure it works now
      2. either rename the created sheet to CanDrink.xls, or alter the code to use the newly created xls file
      3. test fails

      Further analysis
      When we take a look at the binary data of the xls files, and search for the RuleSet (as the program would do), we can see something like this

      1. original xls:
        RuleSet'  org.drools.decisiontable.project.dtable  Import"  org.drools.decisiontable.project.*  Notes  RuleTable ID change	  CONDITION  ACTION  $r:Result() $p:Person
          age $param'  $r.setValue( $p.getName() + " $param");  ID  new ID  <18
          can NOT drink  >= 18	  can drink
        
      2. created xls:
        RuleSet  Import  Notes  RuleTable ID change	  CONDITION  $r:Result() $p:Person
          age $param  ID  <18  >= 18'  org.drools.decisiontable.project.dtable"  org.drools.decisiontable.project.*  ACTION'  $r.setValue( $p.getName() + " $param");  new ID
          can NOT drink	  can drinkÿ
        

      You can see the order of the cell values is different. I suspect the cells are saved in the same order as they were created. But the code relies on the "package" being right after the "RuleSet", which we can't ensure.

      The forementioned method returns "org.drools.decisiontable.project.dtable" when using the original file, and "Import" using the replicated one.

      Show
      To reproduce easily, we can use an existing test and a modified xls file. I have used today's master branch of the drools project (7.33.0-SNAPSHOT). It should be reproducible since 7.21.Final, where both the bug and the test were introduced. Creating the "bad" xls in project drools-decisiontables, find this file drools-decisiontables\src\test\resources\org\drools\decisiontable\project\dtable\CanDrink.xls open a spreadsheet editor (I have used Excel for Office 365, but any should do) create a new xls file and save it parallel next to it, open the CanDrink.xls copy the whole column A from CanDrink.xls to the other file and save it copy the whole column B from CanDrink.xls to the other file and save it We now have two xls files which seem identical in their content. Running the test We're gonna use the org.drools.decisiontable.project.MultiKieBaseTest tests run the test, ensure it works now either rename the created sheet to CanDrink.xls, or alter the code to use the newly created xls file test fails Further analysis When we take a look at the binary data of the xls files, and search for the RuleSet (as the program would do), we can see something like this original xls: RuleSet' org.drools.decisiontable.project.dtable Import" org.drools.decisiontable.project.* Notes RuleTable ID change CONDITION ACTION $r:Result() $p:Person age $param' $r.setValue( $p.getName() + " $param"); ID new ID <18 can NOT drink >= 18 can drink created xls: RuleSet Import Notes RuleTable ID change CONDITION $r:Result() $p:Person age $param ID <18 >= 18' org.drools.decisiontable.project.dtable" org.drools.decisiontable.project.* ACTION' $r.setValue( $p.getName() + " $param"); new ID can NOT drink can drinkÿ You can see the order of the cell values is different. I suspect the cells are saved in the same order as they were created. But the code relies on the "package" being right after the "RuleSet", which we can't ensure. The forementioned method returns "org.drools.decisiontable.project.dtable" when using the original file, and "Import" using the replicated one.
    • NEW
    • NEW

      When compiling xls decision table, wrong ruleset name is parsed from the xls file. This can lead to multiple issues, like rules being filtered out by kmodule.xml configuration.

      According to documentation, decision table begins with a cell at second or third column, having value RuleSet. The cell on the right of this one contains the name of the rule set, which we want to use as a package name.

      The problem lies in naive approach to parsing the package name from the xls file. As you can see in project drools-compiler, class org.drools.compiler.kie.builder.impl.KieBuilderImpl method packageNameFromDtable, it execute as follows:

      1. find "RuleSet" string in the binary data
      2. find and return the nearest string which can act as a valid java package name

      The problem is, the string returned from packageNameFromDtable is NOT the value of the cell next to the RuleSet. It is actually a value of a random cell.

      To understand the problem, we need to understand the binary content of the actual xls file. Every cell is presented as a few bytes, containing cell's value, position, and other information. The "problematic" thing here is, the order of the cells in the binary data is NOT constant. BUT the code really just reads the cell binary next to the "RuleSet" cell.

      Problem is present since version 7.21 as it is caused by a fix for DROOLS-3888 - commit 9a179b6e6b955889200b0258ccd18cd1a5f14b46

      In our case, this results in rules not being loaded, as they are filtered out by kmodule.xml configuration. We have a lot of decision tables we want to migrate from an older drools version, and most of them are now ignored due to this bug.

        1. CanDrink2.xls
          9 kB
          Mario Fusco
        2. CanNotDrink2.xls
          22 kB
          Volodymyr Shymkiv
        3. DROOLS-4967_package_highlight.png
          189 kB
          Volodymyr Shymkiv

              mfusco@redhat.com Mario Fusco
              acc_team Volodymyr Shymkiv (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: