问题
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?
回答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,
来源:https://stackoverflow.com/questions/50870224/java-spark-drools-exception-in-thread-main-java-lang-runtimeexception-canno