Java-Spark-Drools : Exception in thread "main" java.lang.RuntimeException: Cannot find a default KieBase

Raj Source

I have below code which is calling drools rule engine from spark.

Spark Version : 2.3.0

            KieServices ks = KieServices.Factory.get();
            KieContainer kContainer = ks.getKieClasspathContainer();
            ClassTag<KieBase> classTagTest = scala.reflect.ClassTag$.MODULE$.apply(KieBase.class);
            Broadcast<KieBase> broadcastRules = context.broadcast(kContainer.getKieBase(), classTagTest);
            finalJoined.foreach(row -> droolprocess(broadcastRules.value(),row));

here finalJoined is of type Dataset<Row>

public static void droolprocess(KieBase base,Row row){
        StatelessKieSession session = base.newStatelessKieSession();
                //some code to fire rules.
}

When I am running this code in eclipse I am getting below exception :

Exception in thread "main" java.lang.RuntimeException: Cannot find a default KieBase
    at org.drools.compiler.kie.builder.impl.KieContainerImpl.getKieBase(KieContainerImpl.java:336)
    at com.sample.Transformation.main(Transformation.java:66)

My analysis :

due to method of SparkContext

public <T> Broadcast<T> broadcast(T value,
                                  scala.reflect.ClassTag<T> evidence$11)

It is causing issue because I have to pass KieBase as serializable and it is generated at runtime so issue is coming. However I am not sure if this is correct analysis.

kmodule.xml

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
    <kbase name="rules" packages="rules">
        <ksession name="ksession-rules"/>
    </kbase>
    <kbase name="dtables" packages="dtables">
        <ksession name="ksession-dtables"/>
    </kbase>
    <kbase name="process" packages="process">
        <ksession name="ksession-process"/>
    </kbase>
</kmodule>

Can someone provide rootcause and probable way to resolve this?

javaapache-sparkdroolskie

Answers

answered 1 month ago Esteban Aliverti #1

In your kmodule.xml file you are defining 3 KieBases with 3 different names. So far so good. Now, when you want to get a KieBase from the KieContainer, you need to specify the name of the KieBase you want. If you don't specify one, Drools will look for the default KieBase in your kmodule.xml file. If you don't have any default KieBase, Drools will fail with the Exception you are having.

So, either you define what your default KieBase is: <kbase name="rules" packages="rules" default="true">...

Or you specify what KieBase you want: ... context.broadcast(kContainer.getKieBase("rules"), classTagTest);

Hope it helps,

comments powered by Disqus