drools-6 (kie) auto scanning (from spring) of modules and sessions from kie workbench deployed artifacts

StackOverflow https://stackoverflow.com/questions/21303349

  •  01-10-2022
  •  | 
  •  

Question

I am trying to build a web (spring-mvc) application with kie (drools 6) integrated via injection. I have used kie workbench to create a workflow, complied and deployed. I have added reference of this artifact in my project's pom.xml and added the local kie-workbench repository as per this blog post and it's working fine (pulling in the artifact as dependency in my maven/spring project). What I am trying to do is inject the kiesession in one of my service as dependency with following snippet -

@Service
public class TniServiceImpl implements TniService {

@Inject
@KSession("tniSession")
private KieSession tniSession;
...
}

In my root-context.xml, I have added the kie namespace as well along with reference to xsd. I have added org.kie.spring.KModuleBeanFactoryPostProcessor as well as per drools documentation. I am trying to make CDI injection work for KSession scanning and injection (it's already working for my other components in same project, using @Inject). So far I am always getting "No qualifying bean of type [org.kie.api.runtime.KieSession] found for dependency" error. Looks like spring is not able to scan the available kie modules and sessions therein. Need help on following -

  1. Is CDI inject really supported with spring? Do I have to configure kmodules and kession explicitly as mentioned here?
  2. Am I missing something here which should make this scanning and injection work?

My environment is following -

  1. spring 3.2.6-RELEASE (including webmvc and other components)
  2. kie-api-6.0.1.FINAL
  3. kie-spring-6.0.1.FINAL
  4. kie-internal-6.0.1.FINAL

I have already gone through following links but no luck (mostly they are not trying to do what I am) -

  1. Loading Drools/KIE Workbench artifacts directly from the repository
  2. why does loading Drools 6 KIE JAR into code fail?

I'll appreciate if anybody can guide me on what could be the missing piece here or if there's no option but to explicitly define all kmodules/ksessions in spring config file.

Was it helpful?

Solution

I had the same problem and found a solution here: http://drools.46999.n3.nabble.com/Spring-4-0-amp-Drools-6-0-1-Integration-issue-td4028052.html

Basically you will need to inject ApplicationContext instead of kieSession and get xml bean manually.

TniServiceImpl.java

@Service
public class TniServiceImpl implements TniService {

  @Inject 
  ApplicationContext context; 

  KieSession kieSession;

  @PostConstruct 
  public void postConstruct(){ 
    kieSession = (KieSession) context.getBean("ksession1"); 
  }
  ...
}

root-context.xml

   <kie:kmodule id="kmodule1">
     <kie:kbase name="kbase1">
        <kie:ksession name="ksession1" />
     </kie:kbase>
  </kie:kmodule>
  <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor" />

Hope this helps.

UPDATE:

Another way to achieve this is to keep xml identical and instead of trying to inject KieSession, inject KieBase. Then, with the instance of KieBase, create new KieSessions.

@Service
public class TniServiceImpl implements TniService {

    @Autowired
    private KieBase kbase;

    /* inside some method */
    @RequestMapping(method=RequestMethod.GET)
    public @ResponseBody Data getData() {
        KieSession ksession = kbase.newKieSession();
            ...
    }
}

OTHER TIPS

The above answer doesn't work with spring mvc. I found that this is a bug in the existing drools and they are fixing it in the next version. I am stuck at this point since I am using DROOLS in batch mode but I want it to be used in a REST Service hosted on websphere. The above solution works perfectly within a batch program.

This is what I have working with the latest Spring MVC (Spring Boot)

@SpringBootApplication
public class DroolDemoApplication {

public static void main(String[] args) {
    SpringApplication.run(DroolDemoApplication.class, args);
}

@Bean
public KieContainer kieContainer() {
    return KieServices.Factory.get().getKieClasspathContainer();
}

@Bean
public KieSession kieSession() throws IOException {
    return kieContainer().newKieSession("DroolDemoSession");
}
}

and below is the kmodule.xml

<kbase name="DroolDemoKbase" packages="rules">
    <ksession name="DroolDemoSession" />
</kbase>

finally all you do in your controller is

@Autowired
private KieSession kieSession;
    kieSession.fireAllRules();

hope this helps those folks still having issues

I had similar issues with the rules not being triggered, and I solved it by using the 6.2.0.Final version of the kie-ci and kie-spring. I tried versions: 7.7.0, 7.2.0, 6.5.0 and 6.4.0, but none of them worked.

...
<properties>
    <kie.version>6.2.0.Final</kie.version>
</properties>
...
<dependencies>
...
<dependency>
    <groupId>org.kie</groupId>
    <artifactId>kie-ci</artifactId>
    <version>${kie.version}</version>
</dependency>
<dependency>
    <groupId>org.kie</groupId>
    <artifactId>kie-spring</artifactId>
    <version>${kie.version}</version>
</dependency>
...
</dependencies>

What also helped was running mvn dependency:tree and seeing which versions of which artefacts/projects are being used.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top