天天看點

開源規則引擎 Drools 學習筆記 之 -- 1 cannot be cast to org.drools.compiler.kie.builder.impl.InternalKieModule

直接進入正題

我們在使用開源規則引擎

Drools

的時候, 啟動的時候可能會抛出如下異常:

Caused by: java.lang.ClassCastException: cn.com.chengzi.drools.domain.cofing.DroolsAutoConfiguration$1 cannot be cast to org.drools.compiler.kie.builder.impl.InternalKieModule
	at org.drools.compiler.kie.builder.impl.KieServicesImpl.newKieContainer(KieServicesImpl.java:184)
	at org.drools.compiler.kie.builder.impl.KieServicesImpl.newKieContainer(KieServicesImpl.java:172)
	at cn.com.chengzi.drools.domain.cofing.DroolsAutoConfiguration.kieContainer(DroolsAutoConfiguration.java:57)
	at cn.com.chengzi.drools.domain.cofing.DroolsAutoConfiguration$$EnhancerBySpringCGLIB$$f73b7244.CGLIB$kieContainer$2(<generated>)
	at cn.com.chengzi.drools.domain.cofing.DroolsAutoConfiguration$$EnhancerBySpringCGLIB$$f73b7244$$FastClassBySpringCGLIB$$c4bed561.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
	at cn.com.chengzi.drools.domain.cofing.DroolsAutoConfiguration$$EnhancerBySpringCGLIB$$f73b7244.kieContainer(<generated>)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
	... 43 more
 

 
         Caused by: java.lang.ClassCastException: cn.com.chengzi.drools.domain.cofing.DroolsAutoConfiguration$1 cannot be cast to org.drools.compiler.kie.builder.impl.InternalKieModule
	at org.drools.compiler.kie.builder.impl.KieServicesImpl.newKieContainer(KieServicesImpl.java:184)
	at org.drools.compiler.kie.builder.impl.KieServicesImpl.newKieContainer(KieServicesImpl.java:172)
	at cn.com.chengzi.drools.domain.cofing.DroolsAutoConfiguration.kieContainer(DroolsAutoConfiguration.java:57)
	at cn.com.chengzi.drools.domain.cofing.DroolsAutoConfiguration$$EnhancerBySpringCGLIB$$f73b7244.CGLIB$kieContainer$2(<generated>)
	at cn.com.chengzi.drools.domain.cofing.DroolsAutoConfiguration$$EnhancerBySpringCGLIB$$f73b7244$$FastClassBySpringCGLIB$$c4bed561.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
	at cn.com.chengzi.drools.domain.cofing.DroolsAutoConfiguration$$EnhancerBySpringCGLIB$$f73b7244.kieContainer(<generated>)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
	... 43 more
           

檢視發現

KieServicesImpl

類中的

newKieContainer

發現抛出了類型轉換異常:

public KieContainer newKieContainer(String containerId, ReleaseId releaseId, ClassLoader classLoader) {
        InternalKieModule kieModule = (InternalKieModule) getRepository().getKieModule(releaseId);
        if (kieModule == null) {
            throw new RuntimeException("Cannot find KieModule: " + releaseId);
        }
        if (classLoader == null) {
            classLoader = kieModule.getModuleClassLoader();
        }
        KieProject kProject = new KieModuleKieProject( kieModule, classLoader );
        if (classLoader != kProject.getClassLoader()) {
            // if the new kproject has a different classloader than the original one it has to be initialized
            kProject.init();
        }
<pre><code>	if (containerId == null) {
	    KieContainerImpl newContainer = new KieContainerImpl( UUID.randomUUID().toString(), kProject, getRepository(), releaseId );
		return newContainer;
	}
	if ( kContainers.get(containerId) == null ) {
        KieContainerImpl newContainer = new KieContainerImpl( containerId, kProject, getRepository(), releaseId );
        KieContainer check = kContainers.putIfAbsent(containerId, newContainer);
        if (check == null) {
        	return newContainer;
        } else {
        	newContainer.dispose();
        	throw new IllegalStateException("There's already another KieContainer created with the id "+containerId);
        }
    } else {
        throw new IllegalStateException("There's already another KieContainer created with the id "+containerId);
    }
}
</code></pre>
<p> 

 
         public KieContainer newKieContainer(String containerId, ReleaseId releaseId, ClassLoader classLoader) {

InternalKieModule kieModule = (InternalKieModule) getRepository().getKieModule(releaseId);

if (kieModule == null) {

throw new RuntimeException("Cannot find KieModule: " + releaseId);

}

if (classLoader == null) {

classLoader = kieModule.getModuleClassLoader();

}

KieProject kProject = new KieModuleKieProject( kieModule, classLoader );

if (classLoader != kProject.getClassLoader()) {

// if the new kproject has a different classloader than the original one it has to be initialized

kProject.init();

}


       
<span class="hljs-keyword">if</span> (containerId == <span class="hljs-literal">null</span>) {
	    KieContainerImpl newContainer = <span class="hljs-keyword">new</span> KieContainerImpl( UUID.randomUUID().toString(), kProject, getRepository(), releaseId );
		<span class="hljs-keyword">return</span> newContainer;
	}
	<span class="hljs-keyword">if</span> ( kContainers.<span class="hljs-keyword">get</span>(containerId) == <span class="hljs-literal">null</span> ) {
        KieContainerImpl newContainer = <span class="hljs-keyword">new</span> KieContainerImpl( containerId, kProject, getRepository(), releaseId );
        KieContainer check = kContainers.putIfAbsent(containerId, newContainer);
        <span class="hljs-keyword">if</span> (check == <span class="hljs-literal">null</span>) {
        	<span class="hljs-keyword">return</span> newContainer;
        } <span class="hljs-keyword">else</span> {
        	newContainer.dispose();
        	<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"There's already another KieContainer created with the id "</span>+containerId);
        }
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"There's already another KieContainer created with the id "</span>+containerId);
    }
}
           

此為初始化

drl

檔案時的異常, 說明我們的

drl

檔案不規範,

Drools

不能解析成功.

我仔細檢查了一下:

rule "read-Reading-speed"
when
    $rlt:ReadingLevelTest(totalWordsNum != null,totalSecondTime != null)
    $rl:ReadingLevel(readingSpeed == null)
then
    $rl.setReadingSpeed($rlt.getTotalWordsNum()/$rlt.getTotalSecondTime()/60);
    update($rl)
    System.out.println("測評結果讀速: " + $rl.toString());
 end
 

 
         rule "read-Reading-speed"
when
    $rlt:ReadingLevelTest(totalWordsNum != null,totalSecondTime != null)
    $rl:ReadingLevel(readingSpeed == null)
then
    $rl.setReadingSpeed($rlt.getTotalWordsNum()/$rlt.getTotalSecondTime()/60);
    update($rl)
    System.out.println("測評結果讀速: " + $rl.toString());
 end
           

發現其實是因為在

then

中的

update($rl)

後沒有用分号結尾, 加上分号運作正常.

  • when

    後面每行表達式後面是不需要添加分号結尾的
  • then

    後面為

    java

    代碼, 每行必須使用分号結尾, 如果我們忘記了添加分号,編譯器也會報錯題型的, 但是有一些特例, 比如

    Drools

    提供的方法

    update()

    ,

    insert

    等等, 如果後面不加分号, 編譯器是不會報錯的, 但是運作的時候就會抛出解析失敗!

标題:開源規則引擎 Drools 學習筆記 之 -- 1 cannot be cast to org.drools.compiler.kie.builder.impl.InternalKieModule

作者:chengzime

位址:https://www.chengzime.com.cn/articles/2019/09/11/1568195807017.html

原文位址:https://www.chengzime.com.cn/articles/2019/09/11/1568195807017.html

繼續閱讀