Java Drools BRMS火灾和报警规则未使用statefulsession按预期工作

Java Drools BRMS火灾和报警规则未使用statefulsession按预期工作,java,drools,Java,Drools,我正在尝试执行drools文档中的fire、sprinker和alarm规则 我使用的是drools 6.5运行时,当我使用statefull会话(KIE会话)执行这个示例时,我可以看到下面的输出,它与文档中提到的输出不同 下面是我在工作记忆中插入洒水器和火时看到的输出 我看到的输出是: 一切都好 报警 根据文件,实际输出为: 一切都好 报警 打开厨房的洒水器 打开房间办公室的洒水器 感谢您能帮我弄清楚为什么我还有两条规则没有被解雇 附加源代码: package com.company.lice

我正在尝试执行drools文档中的fire、sprinker和alarm规则

我使用的是drools 6.5运行时,当我使用statefull会话(KIE会话)执行这个示例时,我可以看到下面的输出,它与文档中提到的输出不同

下面是我在工作记忆中插入洒水器和火时看到的输出 我看到的输出是:

一切都好 报警

根据文件,实际输出为:

一切都好 报警 打开厨房的洒水器 打开房间办公室的洒水器

感谢您能帮我弄清楚为什么我还有两条规则没有被解雇


附加源代码:

package com.company.license

import com.sample.dto.*

rule "When there is a fire turn on the sprinkler"
when
    Fire($room : room)
    $sprinkler : Sprinkler( room == $room, on == false )
then
    modify( $sprinkler ) { setOn( true ) };
    System.out.println( "Turn on the sprinkler for room " + $room.getName() );
end

rule "When the fire is gone turn off the sprinkler"
when
    $room : Room( )
    $sprinkler : Sprinkler( room == $room, on == true )
    not Fire( room == $room )
then
    modify( $sprinkler ) { setOn( false ) };
    System.out.println( "Turn off the sprinkler for room " + $room.getName() );
end

rule "Raise the alarm when we have one or more fires"
when
    exists Fire()
then
    insert( new Alarm() );
    System.out.println( "Raise the alarm" );
end

rule "Cancel the alarm when all the fires have gone"
when
    not Fire()
    $alarm : Alarm()
then
    retract( $alarm );
    System.out.println( "Cancel the alarm" );
end


rule "Status output when things are ok"
when
    not Alarm()
    not Sprinkler( on == true )
then
    System.out.println( "Everything is ok" );
end



package com.sample.dto;

public class Alarm {

}

package com.sample.dto;

public class Fire {
    private Room room;

    public Fire(Room room2) {
        // TODO Auto-generated constructor stub
    }

    public Room getRoom() {
        return room;
    }

    public void setRoom(Room room) {
        this.room = room;
    }
}

package com.sample.dto;

public class Room {
    private String name;


    public Room(String name){
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

package com.sample.dto;

public class Sprinkler {
    private Room room;
    private boolean on;

    public Sprinkler(Room room) {
        // TODO Auto-generated constructor stub
        this.room = room;
    }
    public Room getRoom() {
        return room;
    }
    public void setRoom(Room room) {
        this.room = room;
    }
    public boolean isOn() {
        return on;
    }
    public void setOn(boolean on) {
        this.on = on;
    }
}

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

public class FireAlarmStateful {

    public static final void main(String[] args) {
        try {
            // load up the knowledge base
            KieServices ks = KieServices.Factory.get();
            KieContainer kContainer = ks.getKieClasspathContainer();
            KieSession ksession = kContainer.newKieSession("ksession-rules");

            String[] names = new String[]{"kitchen", "bedroom", "office", "livingroom"};
            Map<String,Room> name2room = new HashMap<String,Room>();
            Room kitchen =  new Room("kitchen");
            Room office =  new Room("office");
            ksession.insert( kitchen );
            ksession.insert( office );
            Sprinkler sprinkler1 = new Sprinkler( kitchen);
            Sprinkler sprinkler2 = new Sprinkler( office);
            ksession.insert( sprinkler1 );
            ksession.insert( sprinkler2 );
            ksession.fireAllRules();

            Fire kitchenFire = new Fire( kitchen );
            Fire officeFire = new Fire( office );
            FactHandle kitchenFireHandle = ksession.insert( kitchenFire );
            FactHandle officeFireHandle = ksession.insert( officeFire );
            ksession.fireAllRules();

            ksession.dispose();

        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}


Output I get is : 
Everything is ok
Raise the alarm

Output mentioned in the Drools Documentation:
Everything is ok 
Raise the alarm 
Turn on the sprinkler for room kitchen 
Turn on the sprinkler for room office
package com.company.license
导入com.sample.dto*
规则“发生火灾时,打开喷水装置”
什么时候
火灾($room:room)
$Spreader:Spreader(房间==$room,开==假)
然后
修改($sprayer){setOn(true)};
System.out.println(“打开房间的喷水装置”+$room.getName());
结束
规则“当火熄灭时,关闭洒水器”
什么时候
$room:room()
$Spreader:Spreader(房间==$room,开==真)
非火灾(房间==$room)
然后
修改($sprayer){setOn(false)};
System.out.println(“关闭房间的喷水装置”+$room.getName());
结束
规则“发生一次或多次火灾时发出警报”
什么时候
存在火灾()
然后
插入(新报警());
System.out.println(“发出警报”);
结束
规则“当所有火灾消失时取消警报”
什么时候
不是火
$alarm:alarm()
然后
收回(报警);
System.out.println(“取消报警”);
结束
规则“一切正常时的状态输出”
什么时候
不报警()
非喷水装置(开==真)
然后
System.out.println(“一切正常”);
结束
包com.sample.dto;
公共类警报{
}
包com.sample.dto;
公共级火灾{
包房;
公共消防(2室){
//TODO自动生成的构造函数存根
}
公共休息室{
返回室;
}
公共空间设置室(房间){
这个房间=房间;
}
}
包com.sample.dto;
公共教室{
私有字符串名称;
公共房间(字符串名称){
this.name=名称;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
}
包com.sample.dto;
公共级洒水车{
包房;
私有布尔on;
公共洒水车(房间){
//TODO自动生成的构造函数存根
这个房间=房间;
}
公共休息室{
返回室;
}
公共空间设置室(房间){
这个房间=房间;
}
公共布尔值(){
回报;
}
公共无效设置(布尔值打开){
this.on=on;
}
}
公共类有状态{
公共静态最终void main(字符串[]args){
试一试{
//加载知识库
KieServices=KieServices.Factory.get();
KieContainer kContainer=ks.getKieClasspathContainer();
KieSession ksession=kContainer.newKieSession(“ksession规则”);
字符串[]名称=新字符串[]{“厨房”、“卧室”、“办公室”、“客厅”};
Map name2room=newhashmap();
房间厨房=新房间(“厨房”);
房间办公室=新房间(“办公室”);
K段插入(厨房);
K段插入(办公室);
洒水喷头1=新洒水喷头(厨房);
洒水喷头2=新洒水喷头(办公室);
K段插入件(喷水装置1);
K段插入(R2);
ksession.fireAllRules();
消防厨房火灾=新火灾(厨房);
消防办公室火灾=新火灾(办公室);
FactHandle kitchenFireHandle=ksession.insert(kitchenFire);
FactHandle officeFireHandle=ksSession.insert(officeFire);
ksession.fireAllRules();
ksession.dispose();
}捕获(可丢弃的t){
t、 printStackTrace();
}
}
}
我得到的结果是:
一切都好
报警
Drools文档中提到的输出:
一切都好
报警
打开厨房的洒水器
打开房间办公室的洒水器

我有一个补丁。
Fire
对象的构造函数为空

public Fire(Room room2) {
    // TODO Auto-generated constructor stub
}
我修好了

public Fire(Room room2) {
    this.room =  room2 ;
}

它成功了。

除非你详细说明你一直在测试的内容,否则说什么都没有意义。包括运行会话的应用程序的完整Java代码。附加源代码: