解決「Comparison method violates its general contract!」

The ONE跑MaxProp、Prophet可能(取決於你JDK的版本)會報「java.lang.IllegalArgumentException: Comparison method violates its general contract!」錯誤,致使沒法仿真。java

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+要求全部比較器必須是可傳遞的(transitive),好比有A > B 和B > C,必須得保證有推出A > C(同理,對於=和<也需知足傳遞性)。而The ONE源碼是基於JDK1.6的,JDK1.6沒有該要求。ui

3. 解決方法
解決該問題至少有3種方法。源碼

(1)使用JDK1.6版本運行it

(2)修改The ONE源碼,使其知足傳遞性io

只須要更改Router的比較器Comparator就能夠了,好比MaxProp的MaxPropComparator:編譯

private class MaxPropComparator implements Comparator<Message> {
...
}
(3)從新編譯源碼class

加上一些選項,從新編譯The ONE源碼,使其能在JDK1.6+能正常運行[1]。thread

方法一:在main函數第一行加入以下代碼:date

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

相關文章
相關標籤/搜索