2014-09-04 69 views
0

我正在使用drools 6包为我的应用程序构建和运行drl文件。它的正常工作与静态classes.but,当我使用动态类在规则它投掷误差作为DRL未解析动态加载的类

规则编译错误:[规则名称=“规则1”] COM /样品/ Rule_rule_11982550347.java(2: 28):只能导入一个类型。 com.chainsys.csapp.dynaclass.vo.SupplierdivVO解析为包

即使我已经将我的类加载器加载到知识库中。以下是我的代码。

package com.echain.handler; 

import java.sql.SQLException; 
import java.util.List; 

import org.kie.api.KieBaseConfiguration; 
import org.kie.api.KieServices; 
import org.kie.api.io.ResourceType; 
import org.kie.api.runtime.KieContainer; 
import org.kie.api.runtime.KieSession; 
import org.kie.internal.KnowledgeBase; 
import org.kie.internal.KnowledgeBaseFactory; 
import org.kie.internal.builder.KnowledgeBuilder; 
import org.kie.internal.builder.KnowledgeBuilderConfiguration; 
import org.kie.internal.builder.KnowledgeBuilderError; 
import org.kie.internal.builder.KnowledgeBuilderErrors; 
import org.kie.internal.builder.KnowledgeBuilderFactory; 
import org.kie.internal.io.ResourceFactory; 

import com.chainsys.dynui.handler.DynamicFormHandler; 
import com.chainsys.dynui.vo.PageEntityVO; 
import com.chainsys.dynui.vo.PageInfoVO; 
import com.chainsys.fwk.exception.BaseFrameworkException; 
import com.chainsys.fwk.util.ChainsysReflection; 
import com.chainsys.fwk.util.DynamicClassLoader; 
import com.echain.vo.Message; 

public class Testing { 

public static void main(String[] args) throws Exception { 
    // TODO Auto-generated method stub 
    Testing test = new Testing(); 
    test.fire(); 
} 

@SuppressWarnings("deprecation") 
private void fire() throws Exception { 
    DynamicClassLoader loader = getClassLoader("Supplier"); 
    KnowledgeBase kBase = readKnowledgeBase(loader); 
    KieSession kSession = kBase.newKieSession(); 
    KieServices kService = KieServices.Factory.get(); 

    kSession.setGlobal("out", System.out); 

    kSession.insert(createMessage(kService.getKieClasspathContainer(loader))); 
    kSession.insert(new Message("Pravin", "Hi")); 
    kSession.fireAllRules(); 
    kSession.dispose(); 

} 

public KnowledgeBase readKnowledgeBase(ClassLoader loader) throws Exception { 

    KnowledgeBuilderConfiguration kBuilderConfiguration = 
     KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(null, loader); 
    System.out.println(kBuilderConfiguration); 
    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(kBuilderConfiguration); 

    KieBaseConfiguration kbaseConfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(null, loader); 

    kbuilder.add(ResourceFactory.newByteArrayResource(getRule().getBytes()), ResourceType.DRL); 
    // kbuilder.add(ResourceFactory.newFileResource("./rulefiles/testing.drl"), ResourceType.DRL); 
    KnowledgeBuilderErrors errors = kbuilder.getErrors(); 

    if (errors.size() > 0) { 
     for (KnowledgeBuilderError error : errors) 
      System.err.println(error); 
     throw new IllegalArgumentException("Could not parse knowledge."); 
    } 

    KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbaseConfig); 
    kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); 
    return kbase; 
} 

private String getRule() { 
    StringBuffer ruleContent = new StringBuffer(); 
    ruleContent.append("package com.sample\n\n"); 
    ruleContent.append("import com.chainsys.csapp.dynaclass.vo.SupplierdivVO;\n\n"); 
    ruleContent.append("import com.echain.vo.Message\n\n"); 
    ruleContent.append("global java.io.PrintStream out \n\n"); 
    ruleContent.append("rule \"rule 1\" when \n"); 
    ruleContent.append(" m : Message() \n");// SupplierdivVO(test1==\"welc\") 
    ruleContent.append("then \n"); 
    ruleContent.append("out.println(\"hello\");"); 
    ruleContent.append("end\n"); 
    return ruleContent.toString(); 
} 

private Object createMessage(KieContainer kContainer) { 
    Object o = null; 
    try { 
     Class<?> cl = kContainer.getClassLoader().loadClass("com.chainsys.csapp.dynaclass.vo.SupplierdivVO"); 
     o = cl.newInstance(); 
     ChainsysReflection.setProperty(o, "test1", "welc"); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return o; 
} 

public DynamicClassLoader getClassLoader(String pageName) throws BaseFrameworkException, SQLException, 
    ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException { 

    DynamicFormHandler handler = new DynamicFormHandler(); 
    PageInfoVO infoVO = handler.getPageInfoVO(pageName, 1); 

    List<PageEntityVO> eVO = infoVO.getPageEntityList(); 

    DynamicClassLoader classLoader = new DynamicClassLoader(eVO); 

    return classLoader; 
} 

} 
+0

我希望您的班级SupplierDivVO是公开的。您也可以尝试将类文件保存在相同的包中,例如com.echain.handler – jsjunkie 2014-09-04 05:55:22

+0

,谢谢@jsjunkie。实际上我试图使用一个动态类,它只能在runtime.so中使用,我使用自定义类加载器到知识库配置。上面的代码将适用于静态类。 – 2014-09-04 07:29:33

+0

可能是我没弄清楚,但我想你是在getRule()方法中创建动态类,然后再导入SupplierDivVO。我猜有类加载器的问题。你可以用Class.forname()加载你的类而不是导入。如果您找到解决方案,任何情况都请告诉我们。 – jsjunkie 2014-09-04 10:17:32

回答

0

始终传递URL类加载器以创建知识库。因为drools会将URL类加载器类加载到其工作内存中。

public KnowledgeBase newKBase(URLClassLoader loader) { 

    KnowledgeBuilderConfiguration kbuilderConfig = 
     KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(null, loader); 
    // Create the agent using the builder configuration 
    KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration(); 
    KnowledgeBaseConfiguration kbaseConfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(null, loader); 
    KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbaseConfig); 
    KnowledgeAgent kagent = 
     KnowledgeAgentFactory.newKnowledgeAgent(knowledgeAgentName, kbase, aconf, kbuilderConfig); 
    kbase = kagent.getKnowledgeBase(); 
    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(kbuilderConfig); 

    addRules(kbuilder); 
    KnowledgeBuilderErrors errors = kbuilder.getErrors(); 

    if (errors.size() > 0) { 
     for (KnowledgeBuilderError error : errors) 
      System.err.println(error); 
     throw new IllegalArgumentException("Could not parse knowledge."); 
    } 

    kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); 

    return kbase; 
} 

上述方法将加载规则而不会引发错误。