9

I'm using the following drools configuration file in a Spring Boot application to load/execute rules from a DataBase which runs fine locally but when I try deploying the application to a Server i got an error saying no KieModule Bean found. I added the missing KieModule Bean to my config file and now i'm getting another error Failed to instantiate [org.kie.api.runtime.KieContainer]: Factory method 'kieContainer' threw exception; nested exception is java.lang.RuntimeException: Cannot find KieModule: org.default:artifact:1.0.0-SNAPSHOT. My question is 1) why do i need this Bean and 2) why does the application build/run locally without the missing Bean?

If its a mandatory Bean required for deploying the application, do i need to config it specifically for my environment by adding some properties to my application/POM??

public class DroolsDataBaseConfig {

    @Autowired 
    private DataService dataService;

    @PostConstruct
    public void loadResourcesFromDatabase() {       

        try {
            KieHelper helper = getKieHelper();       
            List<Rule> rulesFromDB = dataService.findAllRules();

            for (Rule rule : rulesFromDB){

                String ruleAsStr = rule.getRule();

                helper.addContent(ruleAsStr, ResourceType.DRL);             
            }

            helper.build(getKieServices().newKieBaseConfiguration());

        } catch (Exception ex) {
            log.error("Exception occured loading rules from Database. Exception is : " + ex);           
        }
     }

     @Bean
     @ConditionalOnMissingBean(KieContainer.class)
     public KieContainer kieContainer() throws IOException {

         final KieRepository kieRepository = getKieServices().getRepository();       

         return getKieServices().newKieContainer(kieRepository.getDefaultReleaseId());      
     }

     @Bean
     @ConditionalOnMissingBean(StatelessKieSession.class)
     public StatelessKieSession statelessKieSession() throws IOException {  
         return kieContainer().newStatelessKieSession();
     }

     private KieServices getKieServices() {
        return KieServices.Factory.get();
     }

     @Bean
     @ConditionalOnMissingBean(KieHelper.class)
     public KieHelper getKieHelper() throws IOException {
         return new KieHelper();
     }

     @Bean
     @ConditionalOnMissingBean(KieModule.class)
     public KieModule kieModule() throws IOException {
         return new KieModule() {
                public ReleaseId getReleaseId() {
                    return getKieServices().getRepository().getDefaultReleaseId();
                }
         };
     }

     @Bean
     @ConditionalOnMissingBean(KieBase.class)
     public KieBase kieBase() throws IOException {
         return kieContainer().getKieBase();
     }
}
Orby
  • 428
  • 1
  • 9
  • 24
  • 8
    For anyone who encounters this issue in the future, the error is very misleading! It turned out to be an issue with one of my rules in the Database that failed to compile. Once I removed the rule in question, the application started up fine. – Orby Aug 14 '17 at 07:51
  • 1
    the same exception, but as you said the issue was with my rules action part – Akhil S Kamath Jun 21 '18 at 05:57

3 Answers3

1

As hinted in the comments, it's a Drools compilation issue! In the logs, I get:

KieProject - Unable to build KieBaseModel:defaultKieBase
[3,14]: [ERR 107] Line 3:14 mismatched input 'java' expecting one of the following tokens: '[package, unit, import, global, declare, function, rule, query]'.

This message doesn’t direct you to the exact error but the general region. I checked the import section, and I had put import in one cell, and then in the list of packages to import, I had put the "import" keyword again. I corrected it to match the examples online, and the spreadsheet compiles!

E. Oon
  • 61
  • 7
0

The KModule has been deployed and started on the application and the application needs it when started.

Both of application service and the Wildfly(business-central) should access the same repository that the KieModule is deployed on. If they are running in different machines you could create a remote repository or running their service by different users on the same machine then you should create a setting.xml file in the .m2 directory of the kie-server service owner.

You should define requirement local and remote repositories in the setting.xml file.

0

Can register module by API (alternative):

     //1: Declare: KieService and KieFileSystem ('kie', 'fileSystem')
     //2: Write: in Kie Filesystem: rules (.drl files)
     
     //Then: 
     //3: Declare: Kie Module (with project's pom.xml 'groupId:artifactId', as of: 'com.mycompany.x.y.z')

     final var module = kie.newKieModuleModel();
     module.newKieBaseModel().addPackage("com.mycompany.x.y.z");

     fileSystem.writeKModuleXML(module.toXML());

      //4: Declare: Kie Repository with releaseId
      //5: Return: KieContainer (with releaseId, [classLoader])  //e.g Thread.currentThread().getContextClassLoader()
Felix Aballi
  • 899
  • 1
  • 13
  • 31