问题描述
我有下面的代码从Spark调用 drools规则引擎。
I have below code which is calling drools rule engine from spark.
Spark版本: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));
此处 finalJoined
类型为 Dataset< Row>
public static void droolprocess(KieBase base,Row row){
StatelessKieSession session = base.newStatelessKieSession();
//some code to fire rules.
}
当我在eclipse中运行此代码时,出现以下异常:
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)
我的分析:
由于 SparkContext的方法
public <T> Broadcast<T> broadcast(T value,
scala.reflect.ClassTag<T> evidence$11)
它引起问题,因为我必须通过 KieBase
作为可序列化的代码,并且它在运行时生成,因此问题来了。但是我不确定这是否是正确的分析。
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?
推荐答案
在您的 kmodule.xml
文件中,您定义了3个 KieBases
具有3个不同的名称。到现在为止还挺好。现在,当您想从 KieContainer
获取 KieBase
时,需要指定<$ c的名称。 $ c> KieBase 。如果您未指定,则Drools将在您的 kmodule.xml
文件中查找默认的 KieBase
。如果您没有任何默认的 KieBase
,Drools将因您遇到的异常而失败。
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.
因此,您可以定义默认的 KieBase
是什么:< kbase name = rules package = rules default = true>。 。
So, either you define what your default KieBase
is: <kbase name="rules" packages="rules" default="true">...
或者您指定想要的 KieBase
: ... context.broadcast(kContainer.getKieBase( rules),classTagTest);
希望有帮助,
这篇关于Java-Spark-Drools:线程“ main”中的异常; java.lang.RuntimeException:找不到默认的KieBase的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!