对于派生类

时间:2017-02-10 15:39:40

标签: java drools optaplanner

我的上下文是一个Java Optaplanner应用程序,它使用Drools进行分数计算(类似于optaplanner示例)。

在基类和派生类中拆分某些类后,我在得分计算中得到一个错误:

Exception in thread "main" java.lang.IllegalStateException: There are errors in a score DRL:
Error Messages:
Message [id=1, kieBase=defaultKieBase, level=ERROR, path=de/.../Rules.drl, line=77, column=0
   text=Unable to Analyse Expression var.type.prop2:
[Error: unable to resolve method using strict-mode: de...PropType.prop2]

访问嵌套变量在主Java代码中运行良好。

当第二级(class1.class2.param)是派生类时,问题与Drools规则中对嵌套变量的访问有关。我尝试用从我更复杂的代码中提取的一个小例子来描述这个(我试着保持它很小,如果一个完整的最小例子会更好我可以尝试扩展它):

规划实体:

@PlanningEntity
public class PlanningE{
    // ...

    @PlanningVariable(valueRangeProviderRefs = {"something"})
    private SomePlanningVar var;
}

这将是计划变量:

public class SomePlanningVar{
    private PropType type;

    //getter, setter, constructor 
    }
}

最后在计划变量中使用的类,保留了一些值。 (请注意PropTypeB扩展PropType):

public class PropType{
    private Integer prop1;

    //getter, setter, constructor 
}

public class PropTypeB extends PropType{
    private Integer prop2;

    // getter setter constructor
}

设置伪代码

...
PropTypeB prop = new PropTypeB(...)
SomePlanningVar pvar = new SomePlanningVar(prop)
...

有问题的流氓规则是:

rule "prop"
    when
        PlanningE($value : var.type.prop2)
    then
        scoreHolder.addSoftConstraintMatch(kcontext, -$value);
end

如果我不在基础和派生类中分割PropType(并且只是将prop2添加到PropType),此规则将正常工作,但在我看来,这种情况继承可能很常见。

Drools似乎在某种程度上看不到派生类的正确签名,尽管在Java代码中这没有问题。

我怀疑我的继承如何在Java和/或Drools(具有强大的Python背景但对Java相对较新)方面有问题,但是现在我看不出是什么。

任何想法出了什么问题?

1 个答案:

答案 0 :(得分:0)

实际上这很简单。看到访问者

var.type.prop2

静态分析(编译器可以执行的唯一操作)检测到var属于SomePlanningVar类,其类型为PropType类。这没有名为prop2的属性 - 故事的结尾。

摆脱困境的方法之一是将prop2添加到父类:

public class PropType{
    private Integer prop2;
    public Integer getProp2(){ return prop2; }
}

PropTypeB将覆盖PropType方法getProp2。如果要捕获错误的调用,可以在PropType.getProp2中抛出异常。

此外,如果您从不创建类PropType的对象,则可以使PropType和PropType.getProp2成为抽象。

您也可以查看课程的设计。当您期望PropTypeB时,为什么在规则中有PropType?针对子类编写规则不是更好吗?