開源規則引擎 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

查看發現 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();
}

	<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

發現其實是因為在 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM