8

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.

Community
  • 1
  • 1
Avnish
  • 1,241
  • 11
  • 19

4 Answers4

4

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();
            ...
    }
}
Perazzo
  • 1,127
  • 13
  • 24
  • There are two challenges that I had while working on this. first, auto scanning of artifacts from spring and second injection. This solution, although works, but doesn't do either. I myself landed up using similar solution. As per http://docs.jboss.org/jbpm/v6.0.1/userguide/jBPMReleaseNotes.html#d0e16995 this should be working with @Inject (at least with kie:module, kie:base and kie:session in my context) but it doesn't. Looks to me JBPM integration with spring is not complete, although they say they have revamped it. – Avnish Mar 14 '14 at 03:52
  • @Avnish i agree with you, looks like JBPM integration with spring is not complete. Is not the most elegant solution, but, before that, i was not even able to run the project, getKieClasspathContainer() was always returning null. In your question, was not clear for me that was working fine without auto scanning/injection. – Perazzo Mar 14 '14 at 13:34
  • @Avnish i uptaded the solution, take a look. – Perazzo Mar 25 '14 at 11:05
  • Thanks @Perazzo, appreciate all the help. I believe this is best which can be done with current version of jbpm/kie. I'll accept this as an answer. Hopefully spring integration will mature in near future and we'll have better solutions (especially in auto scanning of kie modules from classpath) in near future. – Avnish Mar 27 '14 at 18:23
0

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.

user1456599
  • 481
  • 5
  • 11
0

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

srb
  • 45
  • 2
  • 11
0

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.

Aleksandar
  • 3,558
  • 1
  • 39
  • 42