Drools 6.4 KieScanner:如何在Maven中创建和添加Jar规则?

时间:2016-07-19 12:22:09

标签: maven jar drools kie

我是Drools和Maven的初学者,我在使用KieScanner加载规则时遇到了问题。

该项目的目的是能够在永久的KieSession中动态加载规则。我想知道是否有可能使用KieFileSystem管理规则(不确定是否可以在没有处理会话并启动另一个会导致缺少先前插入的事实的情况下),但好的方法是使用KieScanner。

这似乎需要创建一个包含规则并具有Maven ID(ReleaseId)的Jar,但我找不到有关创建这些Jar文件的详细文档。

这样的罐子里应该包含哪些文件? DRL文件,Pom.xml和manifest.mf?

这个Jar文件可以添加到哪里?根据文档,当检测到该文件的新问题时,不应该在类路径中添加它:"一旦模块在类路径上,就不能动态加载其他版本"。

是否需要Maven命令?

有人可以向我提供有关这些要点的信息,或者给我一个链接,说明在KieScanner中创建和部署此类Jar及其管理的信息?非常感谢。

3 个答案:

答案 0 :(得分:1)

以下是使用来自maven存储库的 kjar 的无状态kiesession的示例(代码在scala中,但我相信您会理解您主要编程爪哇)

private val services = KieServices.Factory.get
private val releaseId = services.newReleaseId("com.piedpiper", "demo", "[1.0,2)")
private val kieContainer = services.newKieContainer(releaseId)

val kScanner = services.newKieScanner(kieContainer)
kScanner.start(2000L)

val kieSession = kieContainer.newStatelessKieSession("SimpleSession")

@tailrec
def check() {
  val (aName, aAge) = scala.io.StdIn.readf2("{0} {1,number}")
  val applicant = Applicant(name = aName.asInstanceOf[String], age = aAge.asInstanceOf[Long].toInt, pass = false)
  kieSession.execute(applicant)
  println(s"valid is ${applicant.pass}")
  check()
}

check()

这会使用带有gav com.piedpiper:demo:[1.0,2)的maven查找kjar(iow从1.02的任何版本(不包括在内)。它每两秒检查一次是否有新版本该范围可用。

kjar 包含知识资源,kmodule.xml等(使用kie-maven-plugin插件扩展名编译规则的正确kjar)。在这种情况下,它还包含事实模型(我通常会在不同的maven工件中将其分开。)

上例中使用的规则是

rule "Is of valid age"
when
    $a : Applicant( age > 13, pass==false )
then
    modify($a){
        pass = true
    }
end

将规则更改为例如> 15时,需要2秒才能投入使用。

答案 1 :(得分:0)

非常感谢您对raphaëλ的回应。但我的问题是在能够在Java代码中使用它之前构建jar。

这就是我解决问题的方法。

使用规则

创建kjar文件
  • 该文件必须包含:
    • 文件目录META-INF中的kmodule.xml
    • 文件目录META-INF中的MANIFEST.MF(不确定这是必要的......)
    • DRL文件的路径与其程序包定义的路径相同(我已将DRL文件放在未编译的情况下,并按预期触发)
    • Maven应该存在一个文件pom.xml,但是这个失败了,我不得不使用外部pom.xml
  • 命令:

    jar cvmf META-INF \ MANIFEST.MF example-rules.jar META-INF * rules *

文件kmodule.xml的示例:

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
    <kbase name="base1" default="true" packages="rules">
        <ksession name="session1" type="stateful"  ="true"/>
    </kbase>
</kmodule>

文件MANIFEST.MF:

Manifest-Version: 1.0

将kjar添加到Maven存储库:

  • 命令:

    mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile = example-rules.jar -DomomFile = pom_jar.xml

  • 文件pom_jar.xml用于定义Maven引用,例如这样的文件:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId> test.example</groupId>
        <artifactId>example-rules</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>example-rules</name>
    
        <!-- Output to jar format -->
        <packaging>jar</packaging>
    </project>
    

欢迎任何评论。

答案 2 :(得分:0)

以下是使用MemoryFileSystem创建KJar并使用它创建KieContainer的示例

<强>输入:

  • releaseId - 可能是TimeStamp和UUID
  • ruleContentList - DRL文件字符串化列表
// class hierarchy
public abstract class AbstractLogic
{
    public string DoStufF()
    {
        return DoStufFInternal();
    }

    protected abstract string DoStufFInternal();
}

// Here 'where' constraint is not essential, I'm just lazy enough
// and implemented property setting in the dumbest possible way which required the constraint :)
public abstract class AbstractLogic<T> : AbstractLogic where T: class, new()
{
    protected AbstractLogic()
    {
        SomeProperty = new T();
    }

    public T SomeProperty { get; private set; }
}

public class DefaultLogic : AbstractLogic<ClassA>
{
    protected override string DoStufFInternal()
    {
        return $"Default stuff: SomeProperty = {SomeProperty.ToString()}";
    }
}

public class SpecificLogic : AbstractLogic<ClassB>
{
    protected override string DoStufFInternal()
    {
        return $"Specific stuff: SomeProperty = {SomeProperty.ToString()}";
    }
}

public class ClassA
{
    public override string ToString()
    {
        return "Class A representation";
    }
}

public class ClassB
{
    public override string ToString()
    {
        return "Class B representation";
    }
}

// registering class
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
    .Where(t => t.Name.StartsWith(Settings.GetCurrentMode().ToString()))
    .As<AbstractLogic>()
    .InstancePerLifetimeScope();

// and using it in the controller
[Route("api/[controller]")]
public class DITestController : Controller
{
    private readonly AbstractLogic _logic;

    public DITestController(AbstractLogic logic)
    {
        _logic = logic;
    }

    [HttpGet]
    public IActionResult Get()
    {
        return Ok(_logic.DoStufF());
    }
}