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

2023-12-20

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

我找到了一个answer https://stackoverflow.com/a/22208775/1925388关于这一点并尝试了那里提到的解决方案,但遇到了运行时异常。

使用的代码如下:

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

ruleFile1.drl:

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)

我也读过这段代码 https://github.com/droolsjbpm/drools/blob/master/drools-compiler/src/test/java/org/drools/compiler/integrationtests/DynamicRulesTest.java并注意到它正在使用类似这样的代码将新的规则文件动态添加到KieSession:

KnowledgeBase kbase = SerializationHelper.serializeObject( loadKnowledgeBase( "test_Dynamic1.drl" ) );
Collection<KnowledgePackage> kpkgs = SerializationHelper.serializeObject( loadKnowledgePackages( "test_Dynamic2.drl" ) );
kbase.addKnowledgePackages(kpkgs);

但问题是KnowledgeBase是内部 API,不向最终用户公开。

我正在使用 Drools 6.2.0。

EDIT:

我发现也许KieScanner可以用来实现我想要的。 但我无法找到描述使用的正确示例KieScanner用于添加新的规则文件或替换现有的规则文件。

这个答案 https://stackoverflow.com/a/38530777/1925388包含一些有用的信息,但我无法正确理解它。另外,我更喜欢内存罐子。


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将新规则文件添加到现有知识会话 的相关文章

随机推荐

  • Git fork 版本礼仪 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 当我在 GitHub 上分叉别人的项目 更新文件并更新我自己的分叉时 如何对我的分叉进行版本控制 例如 原始项目是版本1 2 3 我添加了一个小
  • 如何使用 pytest 来断言不引发警告

    我想确保完全没有警告在一项断言中提出 找不到任何明确的答案关于警告的 pytest 文档 https docs pytest org en 3 2 1 warnings html assertwarnings 死链接 3 2 文档不再可用
  • Xlib:以最小化或最大化状态创建窗口

    是否可以使用 Xlib 创建最大化或最小化状态的窗口 如果是这样 我将如何去做呢 像这样的东西 XEvent xev Atom wm state XInternAtom dpy NET WM STATE False Atom max hor
  • 存储库设计模式 - 每个 Dao 都应该有一个存储库吗?

    我的应用程序中有一些 DAO 它们访问数据库以进行 CRUD 操作 比如说新闻 天气和体育 DAO 所以我对需要多少个存储库感到困惑 我应该只使用一个存储库 例如 DataRepository 并让我保存我的数据库和所有 dao 并在其中封
  • 如何从一侧禁用抽屉布局?

    我做了一个双抽屉布局没有操作栏像这样的东西 使用没有 TitleBar 或 ActionBar 的导航抽屉 https stackoverflow com questions 17735621 using navigation drawer
  • 在linux内核模块中运行无限循环

    我制作了一个模块 我想在其中运行无限循环 直到不卸载该模块为止 目前 如果我执行 rmmod 它会通知我模块仍然繁忙 并且在一段时间后内核出现恐慌 while 1 有什么技巧可以让我运行无限循环直到卸载模块 这个循环在什么上下文中运行 这是
  • 使用 pyenv 运行 mod_wsgi

    我正在尝试在 Apache 服务器上运行 python Web 应用程序 我已经安装了 mod wsgi sudo apt get install libapache2 mod wsgi 这是我的站点配置文件
  • 尝试登录 Keycloak Admin WS

    我需要通过可通过路径访问的 Admin WS 在 Keycloak 中配置领域 http KeycloakServer 8081 auth admin realms 所以在邮递员中我运行以下请求 URL http KeycloakServe
  • 错误:使用 html-pdf NPM 时在 Cloud Run 上写入 EPIPE

    在这里我试图将 HTML 转换为 PDF 并使用 html pdf npm https www npmjs com package html pdf https www npmjs com package html pdf 该代码在本地运行
  • 何时使用详细类型说明符

    选择使用详细类型说明符是否有特别充分的理由 例如 在某些情况下 需要使用template or typename用于消除依赖关系歧义的关键字template或键入 但我想不出任何例子会发生这种情况 例如枚举 采取以下代码示例 enum Fo
  • 资源管理器资源集具有错误的值

    我正在开发一个使用本地化 resx 资源文件的 wpf prism 4 应用程序 经过一些调试 它没有按预期工作 我发现资源管理器的所有资源集都具有相同的值 默认 loc resx 的值 我的问题是 那里出了什么问题 先感谢您 好吧 我终于
  • 如何管理 Flash CS4 中具有链接类的库符号以在 Flash Builder 4 中进行编译/调试?

    我正在使用 Flash CS4 以下简称 Flash 构建一个视频播放器来创建图形符号 并使用 Flash Builder 4 FB4 进行编译和调试 以下是我在当前工作流程中采取的步骤 在Flash中创建图形符号 我为播放器创建了一些不同
  • 原生 Android/iOS 开发与 Marmalade SDK [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我们公司正处于原生 Android iPhone 开发和一些跨平台解决方案之间进行选择的边缘 特别是 Marmalade SDK 以前
  • Python try finally 块返回[重复]

    这个问题在这里已经有答案了 下面是有趣的代码 def func1 try return 1 finally return 2 def func2 try raise ValueError except return 1 finally re
  • 由于 AsyncTask 是一个单独的类,如何将 OnPostExecute() 的结果获取到主活动?

    我有这两节课 我的主要活动和扩展活动AsyncTask 现在在我的主要活动中我需要从OnPostExecute in the AsyncTask 我如何将结果传递或获取到我的主要活动 这是示例代码 我的主要活动 public class M
  • in 或 for_each 哪个对每个更可取?

    使用Visual Studio时 我至少可以通过以下三种方式来编写容器遍历 哪种方式更可取 假设 vector
  • Android Studio 2.2 原生开发迁移问题

    在切换到 AS 2 2 之前 我有以下结构来实现我的 C app src main jni Android mk app src main jni Application mk app src main jni headers app sr
  • FluentAssertions,确保 IEnumerable 仅包含单个元素

    我正在编写单元测试 我有一些看起来像这样的东西 Fact public void GetFoos only gets foo1 foo1 included true Foo object foo2 included false Foo ob
  • 不使用加载数据命令填充数据库

    如何填充数据 csv文件 导入 MySql Windows 5 1 而不使用加载数据命令 他们是否试图让您学习脚本语言 如果是的话 Python 怎么样 我刚刚测试了以下代码是否满足您的要求 请注意 您需要下载第 3 方 MySQLdb 模
  • 将新规则文件添加到现有知识会话

    我想向现有的规则文件添加一个新的规则文件 或修改现有的规则文件 KieSession在运行时动态地 我找到了一个answer https stackoverflow com a 22208775 1925388关于这一点并尝试了那里提到的解