Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将新规则文件添加到现有知识会话_Java_Nullpointerexception_Drools_Kie - Fatal编程技术网

Java 将新规则文件添加到现有知识会话

Java 将新规则文件添加到现有知识会话,java,nullpointerexception,drools,kie,Java,Nullpointerexception,Drools,Kie,我想在运行时向现有的KieSession动态添加新的规则文件(或修改现有的规则文件) 我找到了一个与此相关的解决方案,并尝试了其中提到的解决方案,但出现了运行时异常 使用的代码如下: Driver.java: package app1; import java.io.FileInputStream; import java.io.FileNotFoundException; import org.kie.api.KieBase; import org.kie.api.KieServices;

我想在运行时向现有的
KieSession
动态添加新的规则文件(或修改现有的规则文件)

我找到了一个与此相关的解决方案,并尝试了其中提到的解决方案,但出现了运行时异常

使用的代码如下:

Driver.java

package app1;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

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.Message;
import org.kie.api.builder.ReleaseId;
import org.kie.api.builder.Results;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

public class Driver {

  public static final void main(String[] args) {
    try {
      KieServices kieServices = KieServices.Factory.get();
      KieFileSystem kfs = kieServices.newKieFileSystem();

      String ruleFilePath = "src/main/resources/rules/ruleFile1.drl";
      FileInputStream fis = null;
      try {
        fis = new FileInputStream(ruleFilePath);
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      }
      kfs = kfs.write(ruleFilePath, kieServices.getResources().newInputStreamResource(fis));

      KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
      Results results = kieBuilder.getResults();
      if (results.hasMessages(Message.Level.ERROR)) {
        System.out.println("~~ERROR~~:");
        System.out.println(results.getMessages());
        throw new IllegalStateException("### errors ###");
      }

      ReleaseId releaseId1 = kieServices.newReleaseId("org.default", "artifact", "1.0.0-SNAPSHOT");
      KieContainer kieContainer = kieServices.newKieContainer(releaseId1);
      KieBase kieBase = kieContainer.newKieBase(kieServices.newKieBaseConfiguration());

      KieSession kSession = kieBase.newKieSession();
      String s = "hello";
      kSession.insert(s);
      kSession.fireAllRules();

      // I edit the rule file manually at this point.
      System.out.println("Waiting");
      Thread.sleep(5000);

      ReleaseId releaseId2 = kieServices.newReleaseId("org.default", "artifact", "1.0.1-SNAPSHOT");
      kieContainer.updateToVersion(releaseId2);
      kSession.fireAllRules();

      System.out.println("Bye");
    } catch (Throwable t) {
      t.printStackTrace();
    }
  }
}
package app1;

rule "rule1"
when
    s: String()
then
    System.out.println("In rule - " + drools.getRule().getName());
    System.out.println("s = " + s);
end
规则文件1.drl

package app1;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

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.Message;
import org.kie.api.builder.ReleaseId;
import org.kie.api.builder.Results;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

public class Driver {

  public static final void main(String[] args) {
    try {
      KieServices kieServices = KieServices.Factory.get();
      KieFileSystem kfs = kieServices.newKieFileSystem();

      String ruleFilePath = "src/main/resources/rules/ruleFile1.drl";
      FileInputStream fis = null;
      try {
        fis = new FileInputStream(ruleFilePath);
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      }
      kfs = kfs.write(ruleFilePath, kieServices.getResources().newInputStreamResource(fis));

      KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
      Results results = kieBuilder.getResults();
      if (results.hasMessages(Message.Level.ERROR)) {
        System.out.println("~~ERROR~~:");
        System.out.println(results.getMessages());
        throw new IllegalStateException("### errors ###");
      }

      ReleaseId releaseId1 = kieServices.newReleaseId("org.default", "artifact", "1.0.0-SNAPSHOT");
      KieContainer kieContainer = kieServices.newKieContainer(releaseId1);
      KieBase kieBase = kieContainer.newKieBase(kieServices.newKieBaseConfiguration());

      KieSession kSession = kieBase.newKieSession();
      String s = "hello";
      kSession.insert(s);
      kSession.fireAllRules();

      // I edit the rule file manually at this point.
      System.out.println("Waiting");
      Thread.sleep(5000);

      ReleaseId releaseId2 = kieServices.newReleaseId("org.default", "artifact", "1.0.1-SNAPSHOT");
      kieContainer.updateToVersion(releaseId2);
      kSession.fireAllRules();

      System.out.println("Bye");
    } catch (Throwable t) {
      t.printStackTrace();
    }
  }
}
package app1;

rule "rule1"
when
    s: String()
then
    System.out.println("In rule - " + drools.getRule().getName());
    System.out.println("s = " + s);
end
我得到的输出是:

In rule - rule1
s = hello
Waiting
java.lang.NullPointerException
  at org.drools.compiler.kie.util.ChangeSetBuilder.build(ChangeSetBuilder.java:53)
  at org.drools.compiler.kie.builder.impl.KieContainerImpl.update(KieContainerImpl.java:129)
  at org.drools.compiler.kie.builder.impl.KieContainerImpl.updateToVersion(KieContainerImpl.java:106)
  at app1.Driver.main(Driver.java:54)
我还阅读并注意到,它使用了一些类似这样的代码来动态地将新规则文件添加到
KieSession

KnowledgeBase kbase = SerializationHelper.serializeObject( loadKnowledgeBase( "test_Dynamic1.drl" ) );
Collection<KnowledgePackage> kpkgs = SerializationHelper.serializeObject( loadKnowledgePackages( "test_Dynamic2.drl" ) );
kbase.addKnowledgePackages(kpkgs);
KnowledgeBase kbase=SerializationHelper.serializeObject(loadKnowledgeBase(“test_Dynamic1.drl”);
集合kpkgs=SerializationHelper.serializeObject(loadKnowledgePackages(“test_Dynamic2.drl”);
kbase.addKnowledgePackages(kpkg);
但问题是
KnowledgeBase
是一个内部API,不向最终用户公开

我正在使用Drools 6.2.0。

编辑:

我发现也许
KieScanner
可以用来实现我想要的。 但是我找不到一个合适的例子来描述如何使用
KieScanner
来添加新的规则文件或替换现有的规则文件


包含一些有用的信息,但我无法正确理解。另外,我更喜欢内存罐。

我一直怀疑w.r.t.通过添加规则并运行从该规则库派生的会话来动态更改规则库。当WM中存在触发新规则的事实时,这意味着什么?这些新规则修改了事实,从而触发了旧规则,而几秒钟后它们还没有被触发?(我想你知道我的意思。)--如果WM为空,请处理该会话并启动一个新会话。-如果WM不是空的,那要看情况而定,我不会在没有具体应用分析的情况下提出任何建议。