I’m trying to make a simple implementation of RuleBook engine with the follwing class:
package some package;
import com.deliveredtechnologies.rulebook.FactMap;
import com.deliveredtechnologies.rulebook.NameValueReferableMap;
import com.deliveredtechnologies.rulebook.annotation.Given;
import com.deliveredtechnologies.rulebook.annotation.Rule;
import com.deliveredtechnologies.rulebook.annotation.Then;
import com.deliveredtechnologies.rulebook.annotation.When;
import com.deliveredtechnologies.rulebook.model.runner.RuleBookRunner;
import java.util.Random;
public class RuleBookMain {
private static final int RANGE = 10;
private static boolean numberGuessed;
public static void main(String[] args) {
Player p1 = new Player("Andrew");
Player p2 = new Player("Anna");
Guess startingGuess = new Guess(p1);
RuleBookRunner ruleBookRunner = new RuleBookRunner("some package");
NameValueReferableMap<Object> facts = new FactMap<>();
facts.setValue("p1", p1);
facts.setValue("p2", p2);
facts.setValue("guess", startingGuess);
while (!numberGuessed) {
System.out.println("Facts before running rules: " + facts);
ruleBookRunner.run(facts);
}
}
@Rule(order = 1)
public static class NumberGuessedRule {
@Given("p1")
private Player p1;
@Given("p2")
private Player p2;
@Given("guess")
private Guess guess;
@When
public boolean when() {
System.out.println("NumberGuessedRule.when: p1=" + p1 + ", p2=" + p2 + ", guess=" + guess);
boolean result = (guess.number == p1.secret && !guess.author.equals(p1))
||
(guess.number == p2.secret && !guess.author.equals(p2));
System.out.println("NumberGuessedRule.when: result=" + result);
return result;
}
@Then
public void then(FactMap<Object> facts) {
// Add debug statements to check for null values
System.out.println("NumberGuessedRule.then: p1=" + p1 + ", p2=" + p2 + ", guess=" + guess);
Player guessedPlayer = guess.number == p1.secret ? p1 : p2;
System.out.println("Number guessed! " + guessedPlayer + " is leaving the game.");
numberGuessed = true;
}
}
@Rule(order = 2)
public static class WrongGuessRule {
@Given("p1")
private Player p1;
@Given("p2")
private Player p2;
@Given("guess")
private Guess guess;
@When
public boolean when() {
return (guess.number != p1.secret && !guess.author.equals(p1))
||
(guess.number != p2.secret && !guess.author.equals(p2));
}
@Then
public void then(FactMap<Object> facts) {
Player guessingPlayer = guess.number != p1.secret ? p1 : p2;
Guess newGuess = new Guess(guessingPlayer);
facts.setValue("guess", newGuess);
System.out.println(newGuess);
}
}
private static int randomNumber() {
return new Random().nextInt(RANGE);
}
static class Guess {
public Player author;
public int number;
public Guess(Player author) {
this.author = author;
this.number = randomNumber();
}
@Override
public String toString() {
return author + " says '" + number + "'";
}
}
static class Player {
public int secret;
public String name;
public Player(String name) {
this.name = name;
this.secret = randomNumber();
}
@Override
public String toString() {
return name + " (secret=" + secret + ")";
}
}
}
When I run main
I receive the following error:
11:44:34.099 [main] ERROR com.deliveredtechnologies.rulebook.model.GoldenRule -- Error invoking action on class com.deliveredtechnologies.rulebook.model.runner.RuleAdapter$$Lambda$120/0x000001f8110823e8
java.lang.reflect.InvocationTargetException: null
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at com.deliveredtechnologies.rulebook.model.GoldenRule.lambda$invoke$8(GoldenRule.java:176)
at java.base/java.util.Optional.ifPresent(Optional.java:178)
Caused by: java.lang.IllegalArgumentException: null
Nothing worked at all!
I think you should change the name of the package, is it correct?
RuleBookRunner ruleBookRunner = new RuleBookRunner("some package");
Replace it with the following and make sure that is the same as the classes package
RuleBookRunner ruleBookRunner = new RuleBookRunner("somepackage");
And try also to change the parameter of then method to:
NameValueReferableMap<Object> facts
1