2017-02-10 29 views
0

我的上下文是一個Java Optaplanner應用程序,它使用Drools進行分數計算(類似於optaplanner示例)。對於派生類,使用嵌套類進行Drools分數計算失敗

在基類和派生類拆分一些班後,我的分數計算得到一個錯誤:

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) 
... 

問題Drools的規則是:

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

此規則將正常工作時,我不拆PropType在基類和派生類中(並且只需將prop2添加到PropType),但在我看來,這種繼承可能相當常見。

Drools似乎沒有看到派生類的正確簽名,儘管在Java代碼中這沒有問題。

我懷疑我在Java和/或Drools(具有強大的Python背景但對Java相對較新)中繼承的工作方式有問題,但現在我看不到什麼。

任何人有任何想法出了什麼問題?

+0

PlanningE沒有一個稱爲proptype的屬性。我不知道如何通過類型PropType來訪問prop2。 - 向我們展示確切的Java代碼,其中「這個工作沒有問題」。 – laune

+0

@laune是的,你有我。我試圖將一些代碼減少到一個小例子並搞砸了。我希望我糾正了這個例子中的錯誤。我有點不情願將此擴展到一個完整的工作示例,因爲這涉及到完整的optaplanner機制,但如果您認爲這將有助於我做到這一點。 –

+0

Drools和OptaPlanner完全支持多態性。例如,OptaPlanner使用[這些類]進行單元測試(https://github.com/droolsjbpm/optaplanner/tree/master/optaplanner-core/src/test/java/org/optaplanner/core/impl/testdata/domain /擴展)。同樣,Drools也有測試(可能在MiscTest中)。因此,如果在這兩個項目中確實存在bug,請創建一個jira並提交一個包含失敗單元的拉取請求以重現問題。 –

回答

0

其實這很簡單。眼看存取

var.type.prop2 

靜態分析(這是唯一的一個編譯器可以做的)檢測到變種是類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?針對子類寫規則不是更可取的嗎?

+0

我重新檢查過,我不認爲這很簡單(儘管我希望)。 「靜態分析...故事的結尾」:「SomePlanningVar」類接受一個「PropType」作爲var - 但它包括從PropType繼承而來的類,就像PropTypeB一樣。這就是我的意思是「java部分工作正常」。我當然可以用'PropTypeB'實例化'SomePlanningVar',然後訪問'var.prop.prop2'。但是這在編程的Drools部分不起作用。我做了一些測試,並嘗試構建一個最小的例子,也許這一點足以讓問題得以解決。但是非常感謝您的努力! –

+0

然後使用PropType的抽象類是要走的路。如果能夠以某種方式處理對非PropTypeB對象的調用,則該方法不需要是抽象的。 - 否則我會對您的班級層次有所保留。 – laune