刚刚接触drools,自己写了drl文件,但是没有得到预期结果,请各位前辈指教

camelliafr 2008-01-10 09:37:25
我对规则这方面的编码都不会,刚开始做,一点都摸不着门,请各位前辈帮帮忙。谢谢了。IDE是eclipse3.0
我的代码特别简单,就是想试试先使规则引擎转起来,下面是我的一个类
package test.mis.action;

public class PeopleValid {
private int peopleId;
private String msg;

public int getId () {
return peopleId;
}

public void setId (int Id) {
this.peopleId = Id;
}

public String getMsg () {
return msg;
}

public void setMsg (String m) {
this.msg = m;
System.out.println(m);
}
}
下面是我的drl文件:
package TestRules

#list any import classes here.
import Test.mis.action.*


#declare any global variables here

rule "First Rule"
when
#conditions
$p:PeopleValid()
eval($p.getId==5)
then
#actions
System.out.println("12345")

end
下面是我的测试代码:
package test.rules.engine.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Reader;
import java.util.List;

import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.WorkingMemory;
import org.drools.compiler.PackageBuilder;
import org.drools.rule.Package;

import test.mis.action.*;

public class RuleEngineTest
{
private String ruleName;

private RuleBase ruleBase;

private WorkingMemory memory;

private static String msg = "Initiated!";

// 用来测试规则路径的正确性和执行情况。
public static void main(String[] args) throws Exception
{
PeopleValid people = new PeopleValid();
System.err.println("已创建对象!");
people.setId(5);
System.err.println(people.getId());
System.err.println("已赋值!");
RuleEngineTest testEngine = new RuleEngineTest();
testEngine.setRuleName("/test\\rules\\drl\\TestRules.drl");
testEngine.init(people);
System.err.println("------------------------------");
testEngine.getMemory().fireAllRules();
System.out.println(people.getMsg());
System.out.println(msg);
System.err.println("规则成功执行!!!");
}

public void init(PeopleValid p) throws Exception
{
long start1, finish1;
long start2, finish2;// 测试响应时间用的变量
start1 = System.currentTimeMillis();
readRule();
finish1 = System.currentTimeMillis();
System.err.println("readRule需要的时间: " + (finish1 - start1));

start1 = System.currentTimeMillis();
ObjectInputStream oIn = new ObjectInputStream(new FileInputStream("src\\test\\rules\\pkg\\TestRules.pkg"));
Package pkg = (Package)oIn.readObject();
finish1 = System.currentTimeMillis();
System.err.println("解析Package文件流需要的时间: " + (finish1 - start1));

// add the package to a rulebase (deploy the rule package).
start1 = System.currentTimeMillis();
// 生成一个RuleBase实例并bore一个workingMemory
ruleBase = RuleBaseFactory.newRuleBase();
memory = ruleBase.newWorkingMemory();
ruleBase.addPackage(pkg);
// 并且初始化一个WorkingMemory
finish1 = System.currentTimeMillis();
System.err.println("从pkg加载规则文件需要的时间: " + (finish1 - start1));

memory.assertObject(p);
System.err.println("调用规则!");
}

public void tearDown()
{
// 销毁工作内存
memory.clearAgenda();
memory.dispose();
}

public void readRule() throws Exception
{
// read in the source
Reader input = new InputStreamReader(RuleEngineTest.class
.getResourceAsStream(ruleName));
PackageBuilder builder = new PackageBuilder();

long start = System.currentTimeMillis();
builder.addPackageFromDrl(input);
long finish = System.currentTimeMillis();
System.err.println("编译规则文件需要的时间:"+(finish-start));

start = System.currentTimeMillis();
Package pkg = builder.getPackage();
ObjectOutputStream oOut = new ObjectOutputStream(new FileOutputStream("src\\test\\rules\\pkg\\TestRules.pkg"));
oOut.writeObject(pkg);
finish = System.currentTimeMillis();
System.err.println("串行化pkg文件需要的时间:"+(finish-start));
}

public WorkingMemory getMemory()
{
return memory;
}

public RuleBase getRuleBase()
{
return ruleBase;
}

public void setRuleName(String ruleName)
{
this.ruleName = ruleName;
}
}
运行之后就出这样的错误:
已创建对象!
5
已赋值!
Exception in thread "main" java.lang.NoClassDefFoundError: Test/mis/action/PeopleValid (wrong name: test/mis/action/PeopleValid)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.drools.rule.PackageCompilationData$PackageClassLoader.loadClass(PackageCompilationData.java:329)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.codehaus.jfdi.interpreter.ClassTypeResolver.importClass(ClassTypeResolver.java:232)
at org.codehaus.jfdi.interpreter.ClassTypeResolver.resolveType(ClassTypeResolver.java:165)
at org.drools.semantics.java.builder.ColumnBuilder.build(ColumnBuilder.java:98)
at org.drools.semantics.java.builder.GroupElementBuilder.build(GroupElementBuilder.java:71)
at org.drools.semantics.java.RuleBuilder.build(RuleBuilder.java:178)
at org.drools.compiler.PackageBuilder.addRule(PackageBuilder.java:381)
at org.drools.compiler.PackageBuilder.addPackage(PackageBuilder.java:219)
at org.drools.compiler.PackageBuilder.addPackageFromDrl(PackageBuilder.java:148)
at test.rules.engine.test.RuleEngineTest.readRule(RuleEngineTest.java:130)
at test.rules.engine.test.RuleEngineTest.init(RuleEngineTest.java:56)
at test.rules.engine.test.RuleEngineTest.main(RuleEngineTest.java:43)
...全文
1430 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
cuiyansong 2012-09-06
  • 打赏
  • 举报
回复
怎么自动生成drl文件呀?
fastfish425 2008-09-25
  • 打赏
  • 举报
回复
Exception in thread "main" java.lang.NoSuchFieldError: ruleMemo
at org.drools.lang.DRLLexer.<init>(DRLLexer.java:96)
at org.drools.compiler.DrlParser.getParser(DrlParser.java:207)
at org.drools.compiler.DrlParser.parse(DrlParser.java:60)
at org.drools.compiler.PackageBuilder.addPackageFromDrl(PackageBuilder.java:165)
at org.drools.examples.HelloWorldExample.main(HelloWorldExample.java:32)
camelliafr 2008-01-16
  • 打赏
  • 举报
回复
多谢大家的帮忙,问题已解决,应该是那个字段和属性的问题,还有就是package有点问题。
十分感谢大家热情相助!!!
camelliafr 2008-01-16
  • 打赏
  • 举报
回复
文档文档!!ljj508@163.com
谢谢13楼
myhomevan 2008-01-16
  • 打赏
  • 举报
回复
Ralph_Gao,

中英文的drools文档发给我,多谢 aleaangela@yahoo.ca

Erice 2008-01-15
  • 打赏
  • 举报
回复
至于你说的语法手册,我好像有3.1 的,4.0 的不是电子文档。你可以在JBOSS社区下载
Erice 2008-01-15
  • 打赏
  • 举报
回复
() 里使用的是你的Fields 而非Property
camelliafr 2008-01-15
  • 打赏
  • 举报
回复
多谢各位前辈啊,规则的语法在哪里可以找到啊?我找了半天也没见到。实用手册里好像也没有。我用一个例子改了改,发现括号里的名称好像也有要求似的,比如:
when
p : PeopleValid ( peopleId == 5 )
then
...
会提示无法创建peopleId的文字解析器,要是将peopleId改成id,错误就消失了。可是在我这篇帖子的开始自己写的规则文件里就不提示这个错误。晕了。

另外回复5楼,我在执行规则前有把对象放入工作区,是用assertobject(),在init函数的末尾。
camelliafr 2008-01-15
  • 打赏
  • 举报
回复
To 12楼:没关系。
问题还是没有解决-_-!
Ralph_Gao 2008-01-15
  • 打赏
  • 举报
回复
中英文的drools文档,pm给我你的邮箱,我发给你
Ralph_Gao 2008-01-15
  • 打赏
  • 举报
回复
assertobject()
哦,因为的版本比较新 没有assertobject的方法了,所以给assertobject的注视掉了 sorry!
Ralph_Gao 2008-01-13
  • 打赏
  • 举报
回复
eval 一般是用来调用在Rule 中定义的函数的。
Eval本质上是一个大杂烩(catch all),它允许任何语义代码被执行,只要最后返回一个boolean值。这可以涉及在规则LHS中绑定的变量和在规则Package中定义的函数。使用eval可以减少规则的声明情况以及用一个低性能的引擎获得结果。‘eval’可以在模式的任意位置使用,但最好的方式是作为规则LHS中最后的条件元素增加。(选之《Drools4.0官方使用手册中文》)
我一直是把它当成一个执行表达式的一个方法,什么都可以用。我最常用它来判断数组或list中的某个值是否满足条件 呵呵~~
Erice 2008-01-12
  • 打赏
  • 举报
回复


$p:PeopleValid()
eval($p.getId==5)


可以改成

$p:PeopleValid(id==5)


eval 一般是用来调用在Rule 中定义的函数的。

版本3.1

4.0 后,可以换一种写法

说错了别怪我
Ralph_Gao 2008-01-12
  • 打赏
  • 举报
回复
还有你用的语法好像是很早版本以前的drools,你去下一个新的drools4.2吧 已经不用WorkMemory了,现在的方法是StatefulSession。建议你去下一个drool的使用手册,好像是有中文的,多看看里面的例子,自己好好想一下,测试一下,很容易掌握的 :)
Ralph_Gao 2008-01-12
  • 打赏
  • 举报
回复
首先 你在testEngine.getMemory().fireAllRules(); 前没有把对象insert到内存中,所以你发现了没有规则没有被触发的问题。解决办法是在testEngine.getMemory().fireAllRules(); 前加上testEngine.getMemory().insert(people);
另外
eval($p.getId==5) 应该是 eval($p.getId()==5) 或者drl可以写成
rule "First Rule"
when
#conditions
$p : PeopleValid(id==5)
then
#actions
System.out.println("12345");
end

规则的语法再好好看下。GOOD LUCK!
JBossWeek 2008-01-11
  • 打赏
  • 举报
回复
import的package名称写错了,将drl文件中的import Test.mis.action.* 改为import test.mis.action.* 应该就可以了
camelliafr 2008-01-11
  • 打赏
  • 举报
回复
谢谢楼上的回复。
好像不是分号的问题,加了分号还是这样的错误,嗯,IDE是3.2的,因为我以后想要做个自动生成drl文件的东西,所以现在就是想看看drl的格式,怎么样能让engine正常运转。
richmondlau 2008-01-11
  • 打赏
  • 举报
回复
也许是drl import语句后面没有加“;”...

anyway 建议把IDE升级到3.2,这样可以用drools的plugin写drl,这种drl的错误到了编译的时候再查错比较困难
camelliafr 2008-01-11
  • 打赏
  • 举报
回复
哦,是这样的,原来那个错误没有了。多谢3楼。不过又出现
Exception in thread "main" java.lang.IllegalArgumentException: The rule called First Rule is not valid. Check for compile errors reported.
at org.drools.common.AbstractRuleBase.addRule(AbstractRuleBase.java:348)
at org.drools.reteoo.ReteooRuleBase.addRule(ReteooRuleBase.java:242)
这样的错误,好像是eval函数造成的,如果把eval那句改写成$p.getId==5可以正确执行,但是不执行then语句中的System.out,请教这是怎么回事?执行完的结果是这样的:

已创建对象!
5
已赋值!
编译规则文件需要的时间:125
串行化pkg文件需要的时间:31
readRule需要的时间: 328
解析Package文件流需要的时间: 16
从pkg加载规则文件需要的时间: 187
将对象放入工作区!
------------------------------
规则成功执行!!!

6,787

社区成员

发帖
与我相关
我的任务
社区描述
JBoss技术交流
社区管理员
  • JBoss技术交流社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧