1. ホーム
  2. ジャワ

比較方式が一般契約に違反している!」を解決する。

2022-02-25 03:42:46

MaxProp, Prophetを実行しているONEは、(JDKのバージョンによっては) "java.lang."エラーを報告して、エミュレーションを不可能にする可能性があります。

Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!



at java.util.TimSort.mergeLo(TimSort.java:747)



at java.util.TimSort.mergeAt(TimSort.java:483)



at java.util.TimSort.mergeCollapse(TimSort.java:410)



at java.util.TimSort.sort(TimSort.java:214)



at java.util.TimSort.sort(TimSort.java:173)



at java.util.Arrays.sort(Arrays.java:659)



at java.util.Collections.sort(Collections.java:217)



at routing.MaxPropRouter.tryOtherMessages(MaxPropRouter.java:385)



at routing.MaxPropRouter.update(MaxPropRouter.java:300)



at core.DTNHost.update(DTNHost.java:342)



at core.World.updateHosts(World.java:200)



at core.World.update(World.java:171)



at ui.DTNSimTextUI.runSim(DTNSimTextUI.java:29)



at ui.DTNSimUI.start(DTNSimUI.java:77)



at core.DTNSim.main(DTNSim.java:170)



2. 問題の原因
この問題の原因は、JDK1.6+では、すべての比較演算子が推移的であることが要求されており、例えば、A > BとB > Cがある場合、A > Cを確実に押し出さなければならない(同様に、= と < についても推移性を満たす必要がある)ことにあります。そして、The ONEのソースコードはJDK1.6をベースにしており、その要件がありません。

3. 解決方法
この問題を解決する方法は、少なくとも3つあります。

(1) JDKバージョン1.6で実行する。

(2) 通過性を満たすためのThe ONEソースコードの修正

ルータのコンパレータComparatorを変更するだけです。例えば、MaxPropComparatorをMaxPropに変更します。

private class MaxPropComparator implements Comparator<Message> { (プライベートクラス MaxPropComparator はコンパレータを実装しています) <未定義
...
}
(3) ソースコードの再コンパイル

JDK1.6+で正しく動作するように、The ONEソースコードを再コンパイルするオプションをいくつか追加します[1]。

方法1:main関数の1行目に以下のコードを追加します。

System.setProperty("java.util.Arrays.useLegacyMergeSort", "true") を設定します。
方法2:オプション -Djava.util.Arrays.useLegacyMergeSort=true でコンパイルすると、フルJavaは以下のようにコンパイルされます。

java -Djava.util.Arrays.useLegacyMergeSort=true -d64 -Xms512m -Xmx4g -cp . :lib/ECLA.jar:lib/DTNConsoleConnection.jar core.DTNSim $*。

参考にしてください。
https://stackoverflow.com/questions/13575224/comparison-method-violates-its-general-contract-timsort-and-gridlayout