2016-07-14 83 views
1

有几天我试图在Netbeans上运行Drools,但它不能像我想要的那样工作。我甚至试图让它作为一个maven项目工作,但这并没有奏效。我描述了我做什么来创建该项目,希望有人能给我一个提示。如何获得在Netbeans Web项目(无Maven)中运行的Drools(Kie会话)?

首先我需要它没有maven的工作,因为我被限制不使用它。但是在我把它放入真实的项目之前,我想测试它。

所以首先我创建一个新项目

  1. 文件>新建项目...向导
  2. 之所以选择 “的Java Web” Categorie并使用项目类型 “WEBAPPLICATION”
  3. 选择一个Tomcat Web服务器8和Java EE 7网络
  4. 没有框架,现在(以后休眠)
  5. 创建项目lib文件夹,并把下面的罐子在它:

    • 滴料编译-6.4.0.Final.jar
    • 滴料芯-6.4.0.Final.jar
    • 滴料-decisiontables-6.4.0.Final.jar
    • 滴料-JSR94 -6.4.0.Final.jar
    • 滴料-reteoo-6.4.0.Final.jar
    • 知识API-6.4.0.Final.jar
    • 纪伊-API 6.4.0.Final.jar
    • kie-internal-6.4.0.Final.jar
    • 纪伊-CI-6.4.0.Final.jar
    • mvel2-2.2.6.Final.jar
    • ANTLR运行时,3.5.Final.jar

与此设置我创建类(无论是在包:Drools中) DroolsMain(测试没有网络服务器和GUI更快调试)

public class DroolsMain { 

    private static KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); 
    private static Collection<KnowledgePackage> pkgs; 
    private static KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); 
    private static StatefulKnowledgeSession ksession; 

    public static void main(final String[] args) { 
     init(); 
     initMessageObject(); 
     fireRules(); 
    } 

    private static void init() { 
     String myRule = "import Drools.Message rule \"Hello World 2\" when message:Message (type==\"Test\") then System.out.println(\"Test, Drools!\"); end";  
     Resource myResource = ResourceFactory.newReaderResource((Reader) new StringReader(myRule)); 
     kbuilder.add(myResource, ResourceType.DRL); 

     if(kbuilder.hasErrors()) { 
      System.out.println(kbuilder.getErrors().toString()); 
      throw new RuntimeException("unable to compile dlr"); 
     } 

     pkgs = kbuilder.getKnowledgePackages(); 

     kbase.addKnowledgePackages(pkgs); 

     ksession = kbase.newStatefulKnowledgeSession(); 
    } 

    private static void fireRules() { 
     ksession.fireAllRules(); 
    } 

    private static void initMessageObject() { 
     Message msg = new Message(); 
     msg.setType("Test"); 
     ksession.insert(msg); 
    } 
} 

和上面所用消息

public class Message { 
    private String type; 
    private String message; 

    public String getType() { 
     return type; 
    } 

    public void setType(String type) { 
     this.type = type; 
    } 

    public String getMessage() { 
     return message; 
    } 

    public void setMessage(String message) { 
     this.message = message; 
    } 


} 

我现在可以运行该代码,并有消息返回。

现在,我想与纪伊尝试一下......

我只是在评论DroolsMain main()方法的方法。 ,并将Kie方法放入目前的Drools文档中。 172-174有:

private static void kieTest() { 
     KieServices kieServices = KieServices.Factory.get(); 
     KieContainer kContainer = kieServices.getKieClasspathContainer(); 

     StatelessKieSession kSession = kContainer.newStatelessKieSession(); 
     Applicant bob = new Applicant("Mr. Bob", 16); 
     //assertTrue(bob.isValid()); 
     kSession.execute(bob); 
     //assertFalse(bob.isValid());    
    } 

我没有把Applicant.class放在这里,因为它只是一个有3个属性的bean。 另外我还创建DRL 申请人。DRL文件:

package Drools "Is of valid age" 
import Drools.Applicant 

when 
    $a : Applicant(age < 18) 
then 
    $a.setValid(false); 
end; 

所以这显然是行不通的,因为纪伊有Maven依赖,所以我尝试这样做:1。 添加目录: - DroolsTest /资源/ - DroolsTest /资源/ META-INF - DroolsTest /资源/ META-INF/maven的 - DroolsTest /资源/ Drools的 2.创建DroolsTest /资源/ META-INFkmodule.xml

内容:

<?xml version="1.0" encoding="UTF-8"?> 
<kmodule xmlns="http://www.drools.org/xsd/kmodule"> 
    <kbase name="Drools" packages="Drools"> 
     <ksession name="ksession-drools" /> 
    </kbase> 
</kmodule> 
  • 创建DroolsTest /资源/ META-INF /行家/ pom.properties 内容:(我的groupId包名称),(我的artifactId项目名称)

    的groupId = Drools的 的artifactId = DroolsTest 版本= 1个

  • 放DRL文件位置:DroolsTest /资源/ Drools的/ applicant.drl
  • 编译此抛出RuntimeException:

    Exception in thread "main" java.lang.RuntimeException: Cannot find a default KieSession 
        at org.drools.compiler.kie.builder.impl.KieContainerImpl.findKieSessionModel(KieContainerImpl.java:555) 
        at org.drools.compiler.kie.builder.impl.KieContainerImpl.newKieSession(KieContainerImpl.java:548) 
        at org.drools.compiler.kie.builder.impl.KieContainerImpl.newKieSession(KieContainerImpl.java:531) 
        at Drools.DroolsMain.kieTest(DroolsMain.java:43) 
        at Drools.DroolsMain.main(DroolsMain.java:52) 
    C:\Users\...\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1 
    BUILD FAILED (total time: 3 seconds) 
    

    有没有解决方案让Kiew无需maven工作,或者我可以在没有它的文件中读取?


    UPDATE:

    我试过launes解决方案:

    import java.io.File; 
    import org.kie.api.KieBase; 
    import org.kie.api.KieServices; 
    import org.kie.api.builder.KieBuilder; 
    import org.kie.api.builder.KieFileSystem; 
    import org.kie.api.builder.Results; 
    import org.kie.api.io.Resource; 
    import org.kie.api.runtime.KieContainer; 
    import org.kie.api.runtime.KieSession; 
    
    public class DroolsMain { 
    private void ntry() { 
         KieServices kieServices = KieServices.Factory.get(); 
         KieFileSystem kfs = kieServices.newKieFileSystem(); 
    
         File rule = new File("src/main/resources/Drools/applicant.drl"); 
         Resource res = kieServices.getResources().newFileSystemResource(rule); 
         kfs.write(res); 
         KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll(); 
         Results results = kieBuilder.getResults(); 
    
         System.out.println("---Messages---"); 
         System.out.println(results.getMessages()); 
    
         KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId()); 
         KieBase kieBase = kieContainer.getKieBase(); 
         KieSession kieSession = kieBase.newKieSession(); 
        } 
    
    public static void main(final String[] args) { 
         DroolsMain dm = new DroolsMain(); 
         dm.ntry(); 
        } 
    } 
    

    我还添加了所有罐子从Drools的分布。现在,编译并没有错误

    回答

    2

    这就是我如何做到这一点,没有行家,没有XML:

    public void build() throws Exception { 
        KieServices kieServices = KieServices.Factory.get(); 
        KieFileSystem kfs = kieServices.newKieFileSystem(); 
        //... 
        Resource res = ...; 
        kfs.write("src/main/resources/simple.drl", res); 
        KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll(); 
        Results results = kieBuilder.getResults(); 
        if(results.hasMessages(Message.Level.ERROR)){ 
         System.out.println(results.getMessages()); 
         throw new IllegalStateException("### errors ###"); 
        } 
    
        KieContainer kieContainer = 
         kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId()); 
    
        KieBase kieBase = kieContainer.getKieBase(); 
        kieSession = kieBase.newKieSession(); 
    } 
    

    我通常使用资源,如

    kieServices.getResources().newInputStreamResource(fis) 
    

    因为从文件中读取是更灵活。