2017-02-10 2 views
0

Mein Kontext ist ein Java-Optaplanner-Anwendung, die Drools für die Berechnung der Punktzahl verwendet (ähnlich den Optaplanner-Beispielen).Drools Score-Berechnung mit geschachtelten Klassen fehlschlägt für abgeleitete Klasse

Nach einigen Klassen in Basisklassen und abgeleiteten Klassen aufteilen bekomme ich einen Fehler in der Score-Berechnung:

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] 

Zugang zu den verschachtelten Variablen funktioniert gut in der Haupt Java-Code.

Das Problem hängt mit dem Zugriff auf verschachtelte Variablen in den Drools-Regeln zusammen, wenn die 2. Ebene (class1.class2.param) eine abgeleitete Klasse ist. Ich versuche, aus meinem komplizierten Code extrahierte in einem kleinen Beispiel zu beschreiben (ich versuchte es klein zu halten, wenn ein komplettes minimales Beispiel sei besser kann ich versuchen, sie zu erweitern):

Die Planungsgesellschaft:

@PlanningEntity 
public class PlanningE{ 
    // ... 

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

Dies wird die Planung variabel sein:

public class SomePlanningVar{ 
    private PropType type; 

    //getter, setter, constructor 
    } 
} 

Und schließlich werden die in der Planungsgröße verwendet Klassen, einige Werte zu halten. (Beachten Sie, dass PropTypeB erstreckt PropType):

public class PropType{ 
    private Integer prop1; 

    //getter, setter, constructor 
} 

public class PropTypeB extends PropType{ 
    private Integer prop2; 

    // getter setter constructor 
} 

Setup-Pseudo-Code

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

Die drools Regel in Frage:

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

Diese Regel wird gut funktionieren, wenn ich PropType spalten nicht in einer Basis und abgeleiteten Klasse (und fügen Sie einfach prop2 zu PropType), aber es scheint mir, dass diese Art der Vererbung ziemlich sein könnte verbreitet.

Drools scheint irgendwie nicht die richtige Signatur für die abgeleitete Klasse zu sehen, obwohl dies im Java-Code ohne Probleme funktioniert.

Ich vermute, dass ich etwas falsch mit, wie die Vererbung in Java und/oder Drools funktioniert (mit einem starken Python-Hintergrund, aber relativ neu in Java), aber für jetzt sehe ich nicht was.

Wer irgendwelche Ideen, was schief geht?

+0

PlanningE hat kein Attribut namens proptype. Ich sehe nicht, wie Sie auf prop2 über Typ zugreifen können, der von Klasse PropType ist. - Zeigen Sie uns den exakten Java-Code, wo "das ohne Probleme funktioniert". – laune

+0

@laune Ja, du hast mich. Ich habe versucht, ziemlich viel Code auf ein kleines Beispiel zu reduzieren und es vermasselt. Ich hoffe, ich habe die Fehler im Beispiel korrigiert. Ich zögere, dies auf ein vollständiges Arbeitsbeispiel auszudehnen, da dies die volle optaplanner-Maschinerie beinhaltet, aber wenn Sie denken, dass dies helfen würde, werde ich es tun. –

+0

Polymorphismus wird in Drools und OptaPlanner vollständig unterstützt. Zum Beispiel hat OptaPlanner Einheitentests mit [diesen Klassen] (https://github.com/droolsjbpm/optaplanner/tree/master/optaplanner-core/src/test/java/org/optaplanner/core/impl/testdata/domain /verlängert). Ähnlich hat Drools Tests (wahrscheinlich in MiscTest;). Wenn es also hier einen Fehler gibt, erstellen Sie für jedes Projekt einen Jira und und senden Sie eine Pull-Anforderung mit einer fehlerhaften Einheit, um das Problem zu reproduzieren. –

Antwort

0

Eigentlich ist das ganz einfach. Sehen der Accessor

var.type.prop2 

statische Analyse detektiert (die die einzigen ein Compiler tun kann, sind), dass die Klasse SomePlanningVar var, und seine Art ist die Klasse PropType. Dies hat keine Eigenschaft namens prop2 - Ende der Geschichte.

Einer der Wege aus dem Dilemma ist prop2 zu der übergeordneten Klasse hinzuzufügen:

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

PropTypeB die PropType Methode getProp2 außer Kraft setzen. Sie können eine Ausnahme in PropType.getProp2 auslösen, wenn Sie fehlerhafte Aufrufe abfangen möchten.

Auch PropType und PropType.getProp2 abstract ist möglich, wenn Sie niemals Objekte der Klasse PropType erzeugen.

Sie können auch das Design Ihrer Klassen überprüfen. Warum haben Sie PropType in den Regeln, wenn Sie einen PropTypeB erwarten? Wäre es nicht vorzuziehen, die Regel gegen die Unterklasse zu schreiben?

+0

Ich überprüfte, und ich denke nicht, dass das so einfach ist (obwohl ich gehofft hatte). "Statische Analyse ... Ende der Geschichte.": Die 'SomePlanningVar'-Klasse akzeptiert einen' PropType' als Var - aber dies schließt Klassen ein, die von 'PropType' abgeleitet sind, wie auch' PropTypeB'. Das meinte ich mit "der Java-Teil funktioniert gut". Ich kann natürlich 'SomePlanningVar' mit einem' PropTypeB' instanziieren und dann auf 'var.prop.prop2' zugreifen. Das geht aber nicht im Drools-Teil des Progs. Ich mache ein paar Tests und versuche, ein funktionierendes minimales Beispiel zu bauen, vielleicht reicht das allein, um das Problem zu lösen. Aber vielen Dank für Ihre Bemühungen! –

+0

Dann ist die Verwendung einer abstrakten Klasse für PropType der Weg zu gehen. Die Methode muss nicht abstrakt sein, wenn ihr Aufruf für ein Nicht-PropTypB-Objekt auf irgendeine Weise behandelt werden kann. - Sonst hätte ich Vorbehalte gegen Ihre Klassenhierarchie. – laune

Verwandte Themen