Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only the first rule gets executed in DefaultRulesEngine #316

Closed
qwertbuddy opened this issue Nov 5, 2020 · 2 comments
Closed

Only the first rule gets executed in DefaultRulesEngine #316

qwertbuddy opened this issue Nov 5, 2020 · 2 comments
Milestone

Comments

@qwertbuddy
Copy link

qwertbuddy commented Nov 5, 2020

I created an interface that extends the Rule interface. Then an abstract class that extends my interface. And then a few classes that extend this abstract class. The interface has the getName() method overridden to return getClass().getSimpleName() so that all rule names are automatically unique. But when I register the two rules (either directly or with a Set) only the first rule gets executed. Why is that? Is it because I'm having two classes extend the Rule interface? The fire() method only executed the first rule, does not find the second rule in the rules object(even though I registered it), and just exits. Can you please help?

@fmbenhassine
Copy link
Member

fmbenhassine commented Nov 24, 2020

You need to make sure to correctly override compareTo to use your overridden getName as this is used to compare rules between each others at registration time in the Rules namespace. Here is an example that works as expected based on your description:

import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rule;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.core.DefaultRulesEngine;

public class Launcher {
	public static void main(String[] args) {
		Rules rules = new Rules();
		rules.register(new MyRule1());
		rules.register(new MyRule2());

		RulesEngine rulesEngine = new DefaultRulesEngine();
		rulesEngine.fire(rules, new Facts());
	}

	// I created an interface that extends the Rule interface.
	// The interface has the getName() method overridden to return getClass().getSimpleName()
	interface MyRule extends Rule {

		@Override
		default String getName() {
			return getClass().getSimpleName();
		}
	}

	// Then an abstract class that extends my interface
	static class MyAbstractRule implements MyRule {

		@Override
		public boolean evaluate(Facts facts) {
			return true;
		}

		@Override
		public void execute(Facts facts) {
			System.out.println(getName() + " executed");
		}

		@Override
		public int compareTo(Rule o) {
			return getName().compareTo(o.getName());
		}
	}

	// And then a few classes that extend this abstract class.
	static class MyRule1 extends MyAbstractRule {}
	static class MyRule2 extends MyAbstractRule {}
}

This prints:

[main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Engine parameters { skipOnFirstAppliedRule = false, skipOnFirstNonTriggeredRule = false, skipOnFirstFailedRule = false, priorityThreshold = 2147483647 }
[main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Registered rules:
[main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule { name = 'MyRule1', description = 'description', priority = '2147483646'}
[main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule { name = 'MyRule2', description = 'description', priority = '2147483646'}
[main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Known facts:
[main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rules evaluation started
[main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule 'MyRule1' triggered
[main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule 'MyRule1' performed successfully
[main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule 'MyRule2' triggered
[main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule 'MyRule2' performed successfully
MyRule1 executed
MyRule2 executed

If you change compareTo to something like:

@Override
public int compareTo(Rule o) {
	return 0;
}

You will see that only MyRule1 is executed. The reason is that when registering MyRule2, it will be considered equal to MyRule1 and will not be registered. I believe this is what you are facing.

It seems that this was not explicit enough in the docs, so I updated the Javadocs and wiki accordingly.

Can you please help?

Does this help?

@qwertbuddy
Copy link
Author

Yes, I realized this today morning after breaking my head over it for several days unfortunately. I found the old issue with Annotations in the wiki and realized that I would need to do as you have mentioned above. Thank you though, I'm sure this will help others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants