<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">For those a bit confused by this. As we've not talked about the new kie stuff in detail. We now have two approaches. One is convention and configuration based &nbsp;- which is now the preferred way of doing things. The other is the pragmatic layer, as below. The additional concepts such as KieModule is due to our improved deployment mechanism - which is now maven module based. We'll try and do a detailed write up of this for end users soon.&nbsp;<div><br></div><div>In the mean time I've done a series of examples, which demonstrates both the convention and the api approach - both on their own and used in conjunction:</div><div><a href="https://github.com/droolsjbpm/drools/tree/master/drools-examples-api">https://github.com/droolsjbpm/drools/tree/master/drools-examples-api</a><br><div><br></div><div>The simplest example needs an empty kmodule.xml file:</div><div>https://github.com/droolsjbpm/drools/blob/master/drools-examples-api/default-kiesession/src/main/resources/META-INF/kmodule.xml</div><div><br></div><div>then session can &nbsp;be created from just two lines:</div><div>https://github.com/droolsjbpm/drools/blob/master/drools-examples-api/default-kiesession/src/main/java/org/drools/example/api/defaultkiesession/DefaultKieSessionExample.java</div><div><br></div><div>The kmodule.xml is necessary for discovery, from that we can find all the drl, bpmn2 files for the kiebase - without the user having to specify each file individually.</div><div><br></div><div>However we now support kiemodules. These are named kiebases that are available for lookup, and deployed via maven. Further one kiemodule can now "include" resources from other kiemodules - s owe have better composition.</div><div><br></div><div>This works really well for CDI, where can now remove all boiler plate code and simply use annotations to inject sessions:</div><div>https://github.com/droolsjbpm/drools/blob/master/drools-examples-cdi/cdi-example-with-inclusion/src/main/java/org/drools/example/cdi/cdiexamplewithinclusion/CDIExampleWithInclusion.java</div><div><br></div><div>Mark<br><div><div>On 25 Mar 2013, at 15:56, Geoffrey De Smet &lt;ge0ffrey.spam@gmail.com&gt; wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">
  

    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  
  <div bgcolor="#FFFFFF" text="#000000">
    I've upgraded OptaPlanner to use the KIE api and I have some
    feedback :)<br>
    <br>
    What I want to do:<br>
    <b>Given of list of DRL's on the classpath, build a KieSession.</b><br>
    <br>
    Here's how I did it with the new KIE api:<br>
    <br>
    &nbsp;&nbsp;&nbsp;&nbsp; public KieBase newKieBase(List&lt;String&gt; scoreDrlList) {<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#cc6600">KieServices</font> kieServices =
    KieServices.Factory.get();<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#cc6600">KieResources</font> kieResources
    = kieServices.getResources();<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#cc6600">KieFileSystem</font>
    kieFileSystem = kieServices.newKieFileSystem();<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (String scoreDrl : scoreDrlList) {<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStream scoreDrlIn =
    getClass().getResourceAsStream(scoreDrl);<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // TODO newClassPathResource() instead, but that
    breaks (mfusco is looking at it)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String path =
    "src/main/resources/optaplanner-kie-namespace/" + scoreDrl;<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kieFileSystem.write(path,
    kieResources.newInputStreamResource(scoreDrlIn, "UTF-8"));<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#cc6600">KieBuilder</font> kieBuilder =
    kieServices.newKieBuilder(kieFileSystem);<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kieBuilder.buildAll();<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#cc6600">Results</font> results =
    kieBuilder.getResults();<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (results.hasMessages(Message.Level.ERROR)) {<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new IllegalStateException("There are errors in
    the scoreDrl's:\n"<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + results.toString());<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (results.hasMessages(Message.Level.WARNING)) {<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.warn("There are warning in the scoreDrl's:\n"<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + results.toString());<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#cc6600">KieContainer</font> kieContainer
    = kieServices.newKieContainer(kieBuilder.get<font color="#cc6600">KieModule</font>().getReleaseId());<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#cc6600">KieBase</font> kieBase =
    kieContainer.getKieBase();<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return kieBase;<br>
    &nbsp;&nbsp;&nbsp;&nbsp; }<br>
    <br>
    &nbsp;&nbsp;&nbsp;&nbsp; public KieSession newKieSession() {<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; KieSession kieSession = kieBase.newKieSession();<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return kieSession;<br>
    &nbsp;&nbsp;&nbsp;&nbsp; }<br>
    <br>
    <b>Feedback</b> (note: these are suggestions, not demands):<br>
    <br>
    1) To do this, I needed to get acquainted with <font color="#cc6600">9 new concepts</font>:<br>
    &nbsp;&nbsp;&nbsp; KieServices, KieResources, KieFileSystem, KieBuilder, Results,
    KieModule, KieContainer, KieBase, KieSession.<br>
    I only care about 2 of those:<br>
    - KieSession<br>
    - KieBase (= the factory to build a new KieSession, which I do
    regularly).<br>
    The other 7 concepts probably represent wonderful advanced features
    which I might want to use later on,<br>
    so they should exist,<br>
    But in a simple use case like this, I should not have to see them or
    deal with them.<br>
    <br>
    2) The kie filesystem features leaks into the simple api, even if I
    don't care about the KieFileSystem at all.<br>
    - I should not explicitly need to create a KieFileSystem:<br>
    &nbsp;&nbsp;&nbsp; KieFileSystem kieFileSystem = kieServices.newKieFileSystem();<br>
    - Adding certain Resource types fails if you don't specify the
    fileSystem's path. This fails for example:<br>
    &nbsp;&nbsp;&nbsp; kieFileSystem.write(kieResources.newInputStreamResource(...));<br>
    - For the default KieBase to work, the path needs to start with a <font color="#993399">magical</font> prefix<br>
    &nbsp;&nbsp;&nbsp; String path = "<font color="#993399">src/main/resources</font>/.../"
    + ...;<br>
    <br>
    3) To create a KieBase from that kieFileSystem, I need to explicitly
    do 5+ calls, in the right order:<br>
    - call kieServices.newKieBuilder(...)<br>
    - call kieBuilder.buildAll()<br>
    - call kieBuilder.getKieModule()<br>
    - call kieServices.newKieContainer(...)<br>
    - call kieContainer.getKieBase()<br>
    Some of these have non-obvious parameters.<br>
    I'd rather just call:<br>
    &nbsp; kieFileSystem.buildKieBase()<br>
    <br>
    4) I don't like having to write the boilerplate code to check if the
    are errors:<br>
    &nbsp; if (results.hasMessages(Message.Level.ERROR)) {...}<br>
    If there are errors, then kieFileSystem.buildKieBase() should just
    throw a DroolsRuntimeException.<br>
    <br>
    <b>Solution</b> proposal:<br>
    <br>
    A) Write a facade class that presumes there is only 1 module and the
    user doesn't need (or want to) to access any of those 7 other
    concepts.<br>
    <br>
    &nbsp;&nbsp;&nbsp; public KieBase newKieBase(List&lt;String&gt; scoreDrlList) {<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; KieBaseFactory kieBaseFactory =
    kieServices.newKieBaseFactory();<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (String scoreDrl : scoreDrlList) {<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; kieBaseFactory.addInputStreamResource(scoreDrl, "UTF-8");<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return kieBaseFactory.buildKieBase; // throws exception upon
    compilation error<br>
    &nbsp;&nbsp;&nbsp; }<br>
    <br>
    Mario's KieHelper is similar, but slightly different.<br>
    <br>
    wkr,<br>
    Geoffrey<br>
    <br>
  </div>

_______________________________________________<br>rules-dev mailing list<br>rules-dev@lists.jboss.org<br>https://lists.jboss.org/mailman/listinfo/rules-dev</blockquote></div><br></div></div></body></html>