2017-02-10 15 views
0

私のコンテキストはスコア計算にDroolsを使用するJava Optaplannerアプリケーションです(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コードで正常に動作します。

第2レベル(class1.class2.param)が派生クラスである場合、Droolsルールのネストされた変数へのアクセスに問題があります。私は私のより複雑なコードから抽出された小さな例でこれを説明しよう(私は小さなそれを維持しようとした完全な最小限の例が良いだろうと、私はそれを拡張しようとすることができます):

計画エンティティ:

@PlanningEntity 
public class PlanningE{ 
    // ... 

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

これは、計画変数になります。いくつかの値を保持し、

public class SomePlanningVar{ 
    private PropType type; 

    //getter, setter, constructor 
    } 
} 

と計画変数で使用される最終的なクラス。 (PropTypeBPropTypeを拡張することに注意してください):

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を分割していない場合は、このルールは正常に動作します基底クラスと派生クラスで(ちょうどprop2PropTypeに追加します)、この種の継承はかなり可能性があります 一般。

Droolsは、Javaコードでは問題なく動作しますが、何らかの形で派生クラスに正しいシグネチャが表示されないようです。

Javaおよび/またはDrools(強力なPythonの背景を持ちますが、Javaに比較的新しいもの)で継承がどのように機能するかは間違っていますが、今は何も見えません。

何か問題が起こっている人はいますか?

+0

PlanningEには、proptypeという属性がありません。 prop2クラスのprop2にアクセスする方法がわかりません。 - 「問題なく動作する」Javaコードを正確に表示します。 – laune

+0

@launeはい、あなたは私を持っています。私はかなりのコードを小さな例に減らそうとしてしまいました。この例の誤りを訂正したいと思います。私はこれをフル・プラクティス・マシンにまで拡大することには少し戸惑うが、もしこれが私のやり方に役立つと思うならば、 –

+0

多型は、DroolsとOptaPlannerで完全にサポートされています。たとえば、OptaPlannerには[これらのクラス](https://github.com/droolsjbpm/optaplanner/tree/master/optaplanner-core/src/test/java/org/optaplanner/core/impl/testdata/domain)の単体テストがあります。 /拡張)。同様に、Droolsにはテストがある(おそらくMiscTest;)。だから実際にどちらかのプロジェクトにバグがある場合は、jiraを作成して、問題を再現するために失敗したユニットでプルリクエストを送信してください。 –

答えて

0

実際これは非常に簡単です。アクセサにvarがクラスSomePlanningVarのものであり、その型がクラスPropTypeであることを検出した(行うことができますコンパイラは一つだけである)

var.type.prop2 

静的解析を見て。これは物語の終わりのprop2というプロパティを持っていません。

ジレンマのうち方法の一つは、親クラスにPROP2を追加することです:

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

PropTypeBがPropType方法getProp2をオーバーライドします。誤った呼び出しを捕捉したい場合は、PropType.getProp2に例外をスローすることができます。

また、PropTypeとPropTypeを作成します。getProp2 abstractは、PropTypeクラスのオブジェクトを決して作成しない場合に可能です。

あなたのクラスのデザインも見直したいかもしれません。なぜあなたはPropTypeBを期待するとき、ルールにPropTypeを持っていますか?サブクラスに対してルールを書く方が良いのではないでしょうか?

+0

私は再確認しましたが、これは簡単なことではありません(私は望みましたが)。 "静的解析...記事の終わり": 'SomePlanningVar'クラスは' PropType'をvarとして受け取りますが、これは 'PropType'から派生したクラスを含み、' PropTypeB'もそうです。これは私が "javaの部分がうまくいく"という意味です。私は 'PropTypeB'で' SomePlanningVar'をインスタンス化してから 'var.prop.prop2'にアクセスできます。しかし、これはプロローグの一部であるDroolsでは機能しません。私はいくつかのテストを行い、動作する最小限の例を構築しようとします。おそらくそれだけで問題が解決するのに十分です。しかし、あなたの努力には大変感謝しています! –

+0

次に、PropTypeの抽象クラスを使用する方法があります。このメソッドは、非PropTypeBオブジェクトの呼び出しが何らかの方法で処理できる場合、抽象的である必要はありません。 - そうでなければ、私はあなたのクラス階層に対して予約をしていました。 – laune

関連する問題