潜在 OptaPlanner/Drools 错误:奇怪的 MultiAccumulate ClassCastException
Potential OptaPlanner/Drools Bug: Strange MultiAccumulate ClassCastException
复制说明如下。
版本和使用
我在 OptaPlanner 规划引擎中使用 Drools 进行评分。
- OptaPlanner v8.8.0.Final
- Drools v7.55.0.Final
Question/Issue
具有这种格式的规则是否隐式转换 MyConstraintConfiguration
?
下面的规则是否有无效的accumulate
?
rule "name"
when
$cc : MyConstraintConfiguration()
accumulate(PlanningEntity($key : key, $value : $cc.getCachedValue($key));
$sumKeys : sum($key),
$sumValues : sum($value);
checkSum($sumValues))
then
// scoreHolder.penalize(...)
end
我在实际实现中有一个与此非常相似的规则。它在没有第二个 sum
函数的情况下工作,但添加第二个函数会导致在调用 org.drools.model.functions.Function2$Impl::apply
.
时在生成的 Drools Java 中抛出 ClassCastException
能不能多一个sum
?考虑到 Drools v7.56.0 Doc, Fig. 85
,我怀疑这不是限制
很遗憾,我无法将生成的代码打印出来以供进一步检查。
复制
8号8.xbranch/tag
- 将这段代码添加到
ConferenceConstraintConfiguration
public static final String NOT_A_RULE = "NotARule";
@ConstraintWeight(NOT_A_RULE)
private HardMediumSoftScore notARule = HardMediumSoftScore.ofHard(100_000);
private int value = 1;
public int getValue() {
return this.value;
}
public void setValue(int value) {
this.value = value;
}
public Integer getStringLength(final String s) {
return map.computeIfAbsent(s, String::length);
}
public HardMediumSoftScore getNotARule() {
return this.notARule;
}
public void setNotARule(HardMediumSoftScore notARule) {
this.notARule = notARule;
}
- 将这条废话规则添加到
conferenceSchedulingConstraints.drl
rule "NotARule"
when
$ccc : ConferenceConstraintConfiguration($value : value)
accumulate(Talk($titleLength : $ccc.getStringLength(title));
$totalLength : sum($titleLength),
$totalLength2 : sum($titleLength);
$totalLength > 0)
then
scoreHolder.penalize(kcontext, $totalLength);
end
运行 ConferenceSchedulingApp::main
或 ConferenceSchedulingScoreHardConstraintTest
中的任何测试(在删除 class 级别 @Disabled
之后),您应该得到 ClassCastException
如果这是一个错误,请告诉我,我可以为它创建一个问题。
完整堆栈跟踪:
16:03:56.339 [EventQueue-0] INFO Opened: data\conferencescheduling\unsolvedtalks-6timeslots-5rooms.xlsx
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: class org.optaplanner.examples.conferencescheduling.domain.ConferenceConstraintConfiguration cannot be cast to class org.optaplanner.examples.conferencescheduling.domain.Talk (org.optaplanner.examples.conferencescheduling.domain.ConferenceConstraintConfiguration and org.optaplanner.examples.conferencescheduling.domain.Talk are in unnamed module of loader 'app')
at org.optaplanner.examples.conferencescheduling.solver.P66.LambdaExtractor66506A5C685462CF06C48BF086E06788.apply(LambdaExtractor66506A5C685462CF06C48BF086E06788.java:1)
at org.drools.model.functions.Function2$Impl.apply(Function2.java:35)
at org.drools.model.view.BindViewItem2.eval(BindViewItem2.java:89)
at org.drools.modelcompiler.constraints.BindingEvaluator.evaluate(BindingEvaluator.java:39)
at org.drools.modelcompiler.constraints.BindingEvaluator.evaluate(BindingEvaluator.java:35)
at org.drools.modelcompiler.constraints.LambdaAccumulator$BindingAcc.getAccumulatedObject(LambdaAccumulator.java:142)
at org.drools.modelcompiler.constraints.LambdaAccumulator.accumulate(LambdaAccumulator.java:77)
at org.drools.core.rule.MultiAccumulate.accumulate(MultiAccumulate.java:118)
at org.drools.core.phreak.PhreakAccumulateNode.addMatch(PhreakAccumulateNode.java:736)
at org.drools.core.phreak.PhreakAccumulateNode.doLeftInserts(PhreakAccumulateNode.java:181)
at org.drools.core.phreak.PhreakAccumulateNode.doNode(PhreakAccumulateNode.java:89)
at org.drools.core.phreak.RuleNetworkEvaluator.switchOnDoBetaNode(RuleNetworkEvaluator.java:588)
at org.drools.core.phreak.RuleNetworkEvaluator.evalBetaNode(RuleNetworkEvaluator.java:555)
at org.drools.core.phreak.RuleNetworkEvaluator.evalNode(RuleNetworkEvaluator.java:382)
at org.drools.core.phreak.RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:342)
at org.drools.core.phreak.RuleNetworkEvaluator.outerEval(RuleNetworkEvaluator.java:178)
at org.drools.core.phreak.RuleNetworkEvaluator.evaluateNetwork(RuleNetworkEvaluator.java:136)
at org.drools.core.phreak.RuleExecutor.reEvaluateNetwork(RuleExecutor.java:228)
at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:91)
at org.drools.core.concurrent.AbstractRuleEvaluator.internalEvaluateAndFire(AbstractRuleEvaluator.java:33)
at org.drools.core.concurrent.SequentialRuleEvaluator.evaluateAndFire(SequentialRuleEvaluator.java:43)
at org.drools.core.common.DefaultAgenda.fireLoop(DefaultAgenda.java:869)
at org.drools.core.common.DefaultAgenda.internalFireAllRules(DefaultAgenda.java:816)
at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:808)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.internalFireAllRules(StatefulKnowledgeSessionImpl.java:1345)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1336)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1320)
at org.optaplanner.core.impl.score.director.drools.DroolsScoreDirector.calculateScore(DroolsScoreDirector.java:105)
at org.optaplanner.core.impl.score.DefaultScoreManager.updateScore(DefaultScoreManager.java:46)
at org.optaplanner.examples.common.business.SolutionBusiness.getScore(SolutionBusiness.java:235)
at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame.resetScreen(SolverAndPersistenceFrame.java:719)
at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame.setSolutionLoaded(SolverAndPersistenceFrame.java:686)
at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame$QuickOpenAction.actionPerformed(SolverAndPersistenceFrame.java:247)
at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame.lambda[=14=](SolverAndPersistenceFrame.java:202)
at java.desktop/javax.swing.JList.fireSelectionValueChanged(JList.java:1804)
at java.desktop/javax.swing.JList$ListSelectionHandler.valueChanged(JList.java:1818)
at java.desktop/javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:219)
at java.desktop/javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:186)
at java.desktop/javax.swing.DefaultListSelectionModel.setValueIsAdjusting(DefaultListSelectionModel.java:723)
at java.desktop/javax.swing.JList.setValueIsAdjusting(JList.java:2152)
at java.desktop/javax.swing.plaf.basic.BasicListUI$Handler.mouseReleased(BasicListUI.java:2958)
at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:298)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6632)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
at java.desktop/java.awt.Component.processEvent(Component.java:6397)
at java.desktop/java.awt.Container.processEvent(Container.java:2263)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5008)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4840)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2772)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4840)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:745)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:743)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
这是 Drools 的可执行模型未提供正确的错误消息,因为这部分规则不正确:
$cc : MyConstraintConfiguration()
accumulate(PlanningEntity($key : key,
$value : $cc.getCachedValue($key)
...
您不能在 PlanningEntity
绑定中使用 $cc
变量。
我已经为它提交了 JIRA。
复制说明如下。
版本和使用
我在 OptaPlanner 规划引擎中使用 Drools 进行评分。
- OptaPlanner v8.8.0.Final
- Drools v7.55.0.Final
Question/Issue
具有这种格式的规则是否隐式转换 MyConstraintConfiguration
?
下面的规则是否有无效的accumulate
?
rule "name"
when
$cc : MyConstraintConfiguration()
accumulate(PlanningEntity($key : key, $value : $cc.getCachedValue($key));
$sumKeys : sum($key),
$sumValues : sum($value);
checkSum($sumValues))
then
// scoreHolder.penalize(...)
end
我在实际实现中有一个与此非常相似的规则。它在没有第二个 sum
函数的情况下工作,但添加第二个函数会导致在调用 org.drools.model.functions.Function2$Impl::apply
.
能不能多一个sum
?考虑到 Drools v7.56.0 Doc, Fig. 85
很遗憾,我无法将生成的代码打印出来以供进一步检查。
复制
8号8.xbranch/tag
- 将这段代码添加到
ConferenceConstraintConfiguration
public static final String NOT_A_RULE = "NotARule";
@ConstraintWeight(NOT_A_RULE)
private HardMediumSoftScore notARule = HardMediumSoftScore.ofHard(100_000);
private int value = 1;
public int getValue() {
return this.value;
}
public void setValue(int value) {
this.value = value;
}
public Integer getStringLength(final String s) {
return map.computeIfAbsent(s, String::length);
}
public HardMediumSoftScore getNotARule() {
return this.notARule;
}
public void setNotARule(HardMediumSoftScore notARule) {
this.notARule = notARule;
}
- 将这条废话规则添加到
conferenceSchedulingConstraints.drl
rule "NotARule"
when
$ccc : ConferenceConstraintConfiguration($value : value)
accumulate(Talk($titleLength : $ccc.getStringLength(title));
$totalLength : sum($titleLength),
$totalLength2 : sum($titleLength);
$totalLength > 0)
then
scoreHolder.penalize(kcontext, $totalLength);
end
运行 ConferenceSchedulingApp::main
或 ConferenceSchedulingScoreHardConstraintTest
中的任何测试(在删除 class 级别 @Disabled
之后),您应该得到 ClassCastException
如果这是一个错误,请告诉我,我可以为它创建一个问题。
完整堆栈跟踪:
16:03:56.339 [EventQueue-0] INFO Opened: data\conferencescheduling\unsolvedtalks-6timeslots-5rooms.xlsx
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: class org.optaplanner.examples.conferencescheduling.domain.ConferenceConstraintConfiguration cannot be cast to class org.optaplanner.examples.conferencescheduling.domain.Talk (org.optaplanner.examples.conferencescheduling.domain.ConferenceConstraintConfiguration and org.optaplanner.examples.conferencescheduling.domain.Talk are in unnamed module of loader 'app')
at org.optaplanner.examples.conferencescheduling.solver.P66.LambdaExtractor66506A5C685462CF06C48BF086E06788.apply(LambdaExtractor66506A5C685462CF06C48BF086E06788.java:1)
at org.drools.model.functions.Function2$Impl.apply(Function2.java:35)
at org.drools.model.view.BindViewItem2.eval(BindViewItem2.java:89)
at org.drools.modelcompiler.constraints.BindingEvaluator.evaluate(BindingEvaluator.java:39)
at org.drools.modelcompiler.constraints.BindingEvaluator.evaluate(BindingEvaluator.java:35)
at org.drools.modelcompiler.constraints.LambdaAccumulator$BindingAcc.getAccumulatedObject(LambdaAccumulator.java:142)
at org.drools.modelcompiler.constraints.LambdaAccumulator.accumulate(LambdaAccumulator.java:77)
at org.drools.core.rule.MultiAccumulate.accumulate(MultiAccumulate.java:118)
at org.drools.core.phreak.PhreakAccumulateNode.addMatch(PhreakAccumulateNode.java:736)
at org.drools.core.phreak.PhreakAccumulateNode.doLeftInserts(PhreakAccumulateNode.java:181)
at org.drools.core.phreak.PhreakAccumulateNode.doNode(PhreakAccumulateNode.java:89)
at org.drools.core.phreak.RuleNetworkEvaluator.switchOnDoBetaNode(RuleNetworkEvaluator.java:588)
at org.drools.core.phreak.RuleNetworkEvaluator.evalBetaNode(RuleNetworkEvaluator.java:555)
at org.drools.core.phreak.RuleNetworkEvaluator.evalNode(RuleNetworkEvaluator.java:382)
at org.drools.core.phreak.RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:342)
at org.drools.core.phreak.RuleNetworkEvaluator.outerEval(RuleNetworkEvaluator.java:178)
at org.drools.core.phreak.RuleNetworkEvaluator.evaluateNetwork(RuleNetworkEvaluator.java:136)
at org.drools.core.phreak.RuleExecutor.reEvaluateNetwork(RuleExecutor.java:228)
at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:91)
at org.drools.core.concurrent.AbstractRuleEvaluator.internalEvaluateAndFire(AbstractRuleEvaluator.java:33)
at org.drools.core.concurrent.SequentialRuleEvaluator.evaluateAndFire(SequentialRuleEvaluator.java:43)
at org.drools.core.common.DefaultAgenda.fireLoop(DefaultAgenda.java:869)
at org.drools.core.common.DefaultAgenda.internalFireAllRules(DefaultAgenda.java:816)
at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:808)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.internalFireAllRules(StatefulKnowledgeSessionImpl.java:1345)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1336)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1320)
at org.optaplanner.core.impl.score.director.drools.DroolsScoreDirector.calculateScore(DroolsScoreDirector.java:105)
at org.optaplanner.core.impl.score.DefaultScoreManager.updateScore(DefaultScoreManager.java:46)
at org.optaplanner.examples.common.business.SolutionBusiness.getScore(SolutionBusiness.java:235)
at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame.resetScreen(SolverAndPersistenceFrame.java:719)
at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame.setSolutionLoaded(SolverAndPersistenceFrame.java:686)
at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame$QuickOpenAction.actionPerformed(SolverAndPersistenceFrame.java:247)
at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame.lambda[=14=](SolverAndPersistenceFrame.java:202)
at java.desktop/javax.swing.JList.fireSelectionValueChanged(JList.java:1804)
at java.desktop/javax.swing.JList$ListSelectionHandler.valueChanged(JList.java:1818)
at java.desktop/javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:219)
at java.desktop/javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:186)
at java.desktop/javax.swing.DefaultListSelectionModel.setValueIsAdjusting(DefaultListSelectionModel.java:723)
at java.desktop/javax.swing.JList.setValueIsAdjusting(JList.java:2152)
at java.desktop/javax.swing.plaf.basic.BasicListUI$Handler.mouseReleased(BasicListUI.java:2958)
at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:298)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6632)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
at java.desktop/java.awt.Component.processEvent(Component.java:6397)
at java.desktop/java.awt.Container.processEvent(Container.java:2263)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5008)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4840)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2772)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4840)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:745)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:743)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
这是 Drools 的可执行模型未提供正确的错误消息,因为这部分规则不正确:
$cc : MyConstraintConfiguration()
accumulate(PlanningEntity($key : key,
$value : $cc.getCachedValue($key)
...
您不能在 PlanningEntity
绑定中使用 $cc
变量。
我已经为它提交了 JIRA。