Drools community discusses various usage, issues and questions on google group (https://groups.google.com/g/drools-usage , https://groups.google.com/g/drools-setup) and zulip chat (https://kie.zulipchat.com/#narrow/stream/232677-drools) daily basis.
When we discuss the usage of a specific feature or syntax (for example, "accumulate"), our documentation (https://docs.jboss.org/drools/release/latest/drools-docs/html_single/) is the best resource but there may be cases where users stumble when they try a little different thing from what is written. In that case, a simple reproducer project is very helpful to communicate each other rather than guessing based on a rule snippet.
In the below blog post, Luca explained how to create a kjar reproducer with maven archetype.
https://blog.kie.org/2021/07/how-to-start-contributing-to-drools-executable-model.html
In this blog post, I’d like to explain basic variants of such reproducer projects by sharing my examples. Also such simple projects are useful for beginners to learn Drools.
https://github.com/tkobayas/kiegroup-examples
Note that these example project names have Drools version number at the end (e.g. 7.61). Sorry that I don’t manage them with git branches because I create them sporadically. Anyway, we always recommend to use the latest version. When you clone and try the examples, please modify them to use the latest Drools version.
Basic DRL
https://github.com/tkobayas/kiegroup-examples/tree/master/Ex-basic-drl-7.61
The simplest example. It’s almost the same as a project created by kie-drools-archetype (but not a kjar). getKieClasspathContainer()
is convenient when you collect all assets in your project classpath.
KieServices ks = KieServices.Factory.get();
KieContainer kcontainer = ks.getKieClasspathContainer();
KieBase kbase = kcontainer.getKieBase();
KieSession ksession = kbase.newKieSession();
You can run DroolsTest with your IDE or maven.
$ mvn clean test
...
Hello, John
You can easily create variant projects from this. e.g. Ex-accumulate, Ex-agenda-group …
Note that this example uses non-executable-model. If you want to test an executable-model issue, see Ex-basic-kjar-em or Ex-KieFileSystem-em.
Kjar and Runner
https://github.com/tkobayas/kiegroup-examples/tree/master/Ex-basic-kjar-7.61
https://github.com/tkobayas/kiegroup-examples/tree/master/Ex-basic-kjar-runner-7.61
A simple kjar example. When you build the Ex-basic-kjar project with mvn clean install
, the kjar is installed to your local maven repository. So you can run the kjar with Ex-basic-kjar-runner.
$ mvn clean test
...
Hello, John
See that DroolsTest in Ex-basic-kjar-runner specifies maven GAV (GroupId, ArtifactId, Version) so it can load the kjar from your maven repository.
ReleaseId releaseId = ks.newReleaseId("com.sample", "basic-kjar", "1.0.0");
KieContainer kContainer = ks.newKieContainer(releaseId);
Note that both pprojects have drools-engine-classic
dependency. It means they use non-executable-model. See the next projects for executable-model.
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-engine-classic</artifactId>
<version>${drools.version}</version>
</dependency>
Executable-model Kjar
https://github.com/tkobayas/kiegroup-examples/tree/master/Ex-basic-kjar-em-7.61
https://github.com/tkobayas/kiegroup-examples/tree/master/Ex-basic-kjar-runner-em-7.61
This is "executable-model" version of Ex-basic-kjar / Ex-basic-kjar-runner. Rules and Java codes are the same as non-executable-model version (except its artifactId). You will just find drools-engine
dependency in pom.xml files, which is an assembler dependency for executable-model.
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-engine</artifactId>
<version>${drools.version}</version>
</dependency>
You can run the kjar with the same steps as Ex-basic-kjar / Ex-basic-kjar-runner projects. When running DroolsTest, you will confirm the log that the kjar is built with executable-model.
$ mvn clean test
...
[main] INFO Artifact com.sample:basic-kjar-em:1.0.0 has executable model
...
Hello, John
Programmatically create an in-memory Kjar
https://github.com/tkobayas/kiegroup-examples/tree/master/Ex-KieFileSystem-7.61
If you want to programmatically create an in-memory kjar so that you can have control on which assets to build, you would use KieFileSystem
instead of getKieClasspathContainer()
.
// KieFileSystem is responsible for gathering resources
KieFileSystem kfs = ks.newKieFileSystem();
// You can add your DRL files as InputStream here
kfs.write("src/main/resources/com/sample/Sample1.drl",
ks.getResources().newInputStreamResource(new FileInputStream(new File("work/Sample1.drl"))));
kfs.write("src/main/resources/com/sample/12345.drl",
ks.getResources().newInputStreamResource(new FileInputStream(new File("work/Sample2.drl"))));
// You need to specify a unique ReleaseId per KieContainer (= the unit which you store a set of DRL files)
// ReleaseId consists of "GroupId" + "ArtifactId" + "Version". The same idea of Maven artifact.
ReleaseId releaseId = ks.newReleaseId("com.sample", "my-sample-a", "1.0.0");
kfs.generateAndWritePomXML(releaseId);
// Now resources are built and stored into an internal repository
ks.newKieBuilder(kfs).buildAll();
// You can get a KieContainer with the ReleaseId
KieContainer kcontainer = ks.newKieContainer(releaseId);
See that this example adds work/Sample1.drl
and work/Sample2.drl
files to the KieFileSystem so only rules in these files are fired.
Executable-model with KieFileSystem
https://github.com/tkobayas/kiegroup-examples/tree/master/Ex-KieFileSystem-em-7.61
You can use executable-model with KieFileSystem. The code difference from the previous project is only this line:
ks.newKieBuilder(kfs).buildAll(ExecutableModelProject.class);
Also note that you need to have drools-engine
dependency instead of drools-engine-classic
.
In this example, I additionally enabled this debug log in logback-test.xml
<logger name="org.drools.modelcompiler.builder" level="debug"/>
So you will see generated executable-model Java sources as debug log.
public class RulesCF20A831C922E3C97396E3F20148B0A2RuleMethods0 {
/**
* Rule name: Hello World 1
*/
public static org.drools.model.Rule rule_Hello_32World_321() {
final org.drools.model.Variable<com.sample.Person> var_GENERATED_$pattern_Person$1$ = D.declarationOf(com.sample.Person.class,
DomainClassesMetadataCF20A831C922E3C97396E3F20148B0A2.com_sample_Person_Metadata_INSTANCE,
"GENERATED_$pattern_Person$1$");
org.drools.model.Rule rule = D.rule("com.sample",
"Hello World 1")
.build(D.pattern(var_GENERATED_$pattern_Person$1$),
D.execute(com.sample.P06.LambdaConsequence06CFDB45165A059504338D25A218B880.INSTANCE));
return rule;
}
...
Kie-server example
https://github.com/tkobayas/kiegroup-examples/tree/master/Ex-kie-server-kjar-7.61
https://github.com/tkobayas/kiegroup-examples/tree/master/Ex-kie-server-client-7.61
This is an example to run a kjar in kie-server. Typically, you would create and build a project in business-central and then deploy it to kie-server using business-central UI. But you can also build a kjar with maven and then deploy it to kie-server using kie-server-client API. This is quicker than operating UI so useful for a reproducer and testing back-and-forth.
You can build Ex-kie-server-kjar with maven as usual.
$ mvn clean install
Then run CreateContainer in Ex-kie-server-client to deploy the kjar to your kie-server. Of course, you have to start your kie-server beforehand. You can download jbpm-server-x.x.x.Final-dist.zip via https://jbpm.org which is all-in-one distribution. You will see console log at kie-server side (e.g. WildFly) that tells the kjar is deployed and started.
INFO [org.kie.server.services.impl.KieServerImpl] (default task-2) Container kie-server-kjar-example_1.0.0 (for release id com.sample:kie-server-kjar-example:1.0.0) successfully started
Now you can run StatefulTest or StatelessTest.
$ mvn test -Dtest=StatelessTest
...
-----------------------------------
ServiceResponse[SUCCESS, msg='Container kie-server-kjar-example_1.0.0 successfully called.', result='org.drools.core.runtime.impl.ExecutionResultImpl@682abca7']
results = [hit Hello rule]
And more…
I cannot go through all examples but please just try if you find anything interesting!