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