enhancement
major
defect
major
minor
major
#29723
Model editor class diagram fails with "Comparison method violates its general contract!"
Fehlerbild
Beim Auswählen eines Moduls im Modell-Editor bricht der Aufbau des Klassendiagramms mit einem internen Fehler ab:
java.lang.IllegalArgumentException: Comparison method violates its general contract! at java.base/java.util.TimSort.mergeLo(TimSort.java:781) ... at java.base/java.util.Collections.sort(Collections.java:178) at com.top_logic.graph.layouter.algorithm.crossing.LayerUpCrossingMinimizer.sortEdges(LayerUpCrossingMinimizer.java:148) at com.top_logic.graph.layouter.algorithm.crossing.LayerCrossingMinimizer.initCrossings(LayerCrossingMinimizer.java:79) ... at com.top_logic.graph.layouter.Sugiyama.layout(Sugiyama.java:80) at com.top_logic.graph.diagramjs.server.util.GraphModelUtil.getLayoutedGraph(GraphModelUtil.java:141) ... at com.top_logic.graph.diagramjs.server.DiagramJSGraphComponent.onSelectionChange(DiagramJSGraphComponent.java:277)
Der Fehler tritt abhängig von der Gestalt des Modells auf (Anzahl und Reihenfolge der Kanten). In der Jenkins-Build 16424 (PR zu #29715) sind dadurch rund 40 Scripted-Tests des Demos fehlgeschlagen, die über den Modell-Editor Attribute oder Typen anlegen.
Ursache
LexicographicEdgeComparator und LexicographicEdgeReversedComparator (com.top_logic.graph.layouter.model.comparator) vergleichen Kanten mit gleicher Quelle zuletzt nach der Position ihres Ziels, liefern dabei aber nie 0`: bei gleicher Zielposition ergibt der Vergleich in beide Richtungen `1, sogar für eine Kante mit sich selbst. Parallele Kanten (mehrere Kanten zwischen denselben beiden Knoten, z.B. Vererbung und Referenz zwischen denselben Typen) verletzen damit den Comparator-Vertrag. TimSort erkennt die Verletzung nur bei bestimmten Größen und Eingabereihenfolgen, daher tritt der Fehler nur bei manchen Modellen auf.
Lösung
Beide Vergleicher vergleichen die Zielpositionen mit Integer.compare. Ein Test prüft beide Vergleicher auf einem Graphen mit parallelen Kanten (Gleichheit mit sich selbst, Antisymmetrie, Sortieren in zufälliger Ausgangsreihenfolge).