如何让 Drools (Kie Session) 在 Netbeans Web Project (No Maven) 中



几天来,我一直在尝试在Netbeans中运行Drools,但它只是没有像我想要的那样工作。我什至试图让它作为一个 maven 项目工作,但这并没有很好地工作。我描述了我为创建项目所做的工作,希望有人可以给我一个提示。

首先,我需要它在没有 maven 的情况下工作,因为我被限制不能使用它。但在我把它放在真正的项目中之前,我想测试它。

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

  1. 文件>新建项目..巫师
  2. 选择"Java Web"分类并使用Projecttype "Webapplication"
  3. 选择tomcat 8 Web服务器和Java EE 7 Web
  4. 暂时没有框架(稍后休眠)
  5. 在项目中创建 lib 文件夹并在其中放置以下 jar:

    • 流口水编译器-6.4.0.最终.jar
    • 流口水-核心-6.4.0.最终.jar
    • 流口水-决策表-6.4.0.最终.jar
    • 流口水-jsr94-6.4.0.最终.jar
    • 流口水-reteoo-6.4.0.最终.jar
    • 知识 api-6.4.0.最终.jar
    • kie-api-6.4.0.Final.jar
    • kie-internal-6.4.0.final.jar
    • kie-ci-6.4.0.final.jar
    • mvel2-2.2.6.最终版.jar
    • antlr-runtime-3.5.Final.jar

通过此设置,我创建了类(都在包中:流口水)DroolsMain (在没有 Web 服务器和 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;
    }

}

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

现在我想和Kie一起尝试一下...

我只是评论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());            
    }

我没有把申请人.class放在这里,因为它只是一个具有 3 个属性的豆子。我还创建了DRL申请人.drl文件:

package Drools "Is of valid age"
import Drools.Applicant
when
    $a : Applicant(age < 18)
then
    $a.setValid(false);
end;

所以这显然不起作用,因为 Kie 有 maven 依赖项,所以我尝试了这个: 1. 添加目录: - 流口水测试/资源/- 流口水测试/资源/元信息中 - DroolsTest/resources/META-INF/maven - 流口水测试/资源/流口水 2. 创建 DroolsTest/resources/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>
  1. Create DroolsTest/resources/META-INF/maven/pom.properties内容:(组 ID 我的包名称),(工件 ID 我的项目名称)

    groupId=DroolsartifactId=DroolsTest版本=1

  2. 将drl文件放在这里:DroolsTest/resources/Drools/applicant.drl

编译它会抛出一个运行时异常:

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...AppDataLocalNetBeansCache8.1executor-snippetsrun.xml:53: Java returned: 1
BUILD FAILED (total time: 3 seconds)

有没有解决方案可以让 Kiew 在没有 maven 的情况下工作,或者我可以在没有 maven 的情况下读取文件吗?


更新:

我尝试了劳恩斯溶液:

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();
    }
}

我还添加了流口水分布中的所有罐子。现在它编译并且没有错误

这就是我的做法,没有maven,没有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 )

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

最新更新