java.lang.IllegalArgumentException: Comparison method violates its general contract!

Jenkins JIRA | Charles Stephens | 2 years ago
  1. 0

    [JENKINS-27770] AdvancedQueueSorter call to sort violates the comparison contract - Jenkins JIRA

    jenkins-ci.org | 1 year ago
    java.lang.IllegalArgumentException: Comparison method violates its general contract!
  2. 0

    At random times, jobs are unable to start builds and several exceptions are thrown in the log: {noformat} Apr 06, 2015 6:32:21 AM hudson.triggers.SafeTimerTask run SEVERE: Timer task hudson.model.Queue$MaintainTask@5116dc28 failed java.lang.IllegalArgumentException: Comparison method violates its general contract! at java.util.TimSort.mergeHi(TimSort.java:868) at java.util.TimSort.mergeAt(TimSort.java:485) at java.util.TimSort.mergeForceCollapse(TimSort.java:426) at java.util.TimSort.sort(TimSort.java:223) 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 jenkins.advancedqueue.sorter.AdvancedQueueSorter.sortBuildableItems(AdvancedQueueSorter.java:81) at hudson.model.Queue.maintain(Queue.java:1021) at hudson.model.Queue$MaintainTask.doRun(Queue.java:1994) at hudson.triggers.SafeTimerTask.run(SafeTimerTask.java:54) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.j ava:178) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293 ) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) {noformat} The call to sortBuildableItems() calls the java.utils.Collections.sort() which had a change semantics from Java 6 to 7. Specifically there is a [contract constraint|https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html#compare%28T,%20T%29] in compare() that requires that {{sgn(compare(x, y)) == -sgn(compare(y, x))}} for all {{x}} and {{y}}. Since any two calls to getInQueueSince() will return different values for any BuildableItem object, it's possible that while the signs maybe the same, the absolute values are not and the exception is thrown. {code:java} // Sort Collections.sort(items, new Comparator<BuildableItem>() { public int compare(BuildableItem o1, BuildableItem o2) { float o1weight = getCalculatedWeight(o1); float o2weight = getCalculatedWeight(o2); if (o1weight > o2weight) { return 1; } if (o1weight < o2weight) { return -1; } return (int) (o1.getInQueueSince() - o2.getInQueueSince()); } }); {code} There is a workaround by disabling timsort and reverting to the Java 6's mergesort using {{-Djava.util.Arrays.useLegacyMergeSort=true}}. The problem longterm is that the legacy sorting algorithm might go away in a future release of Java. Recommend changing the subtraction operation to a set of comparisons instead.

    Jenkins JIRA | 2 years ago | Charles Stephens
    java.lang.IllegalArgumentException: Comparison method violates its general contract!
  3. 0

    At random times, jobs are unable to start builds and several exceptions are thrown in the log: {noformat} Apr 06, 2015 6:32:21 AM hudson.triggers.SafeTimerTask run SEVERE: Timer task hudson.model.Queue$MaintainTask@5116dc28 failed java.lang.IllegalArgumentException: Comparison method violates its general contract! at java.util.TimSort.mergeHi(TimSort.java:868) at java.util.TimSort.mergeAt(TimSort.java:485) at java.util.TimSort.mergeForceCollapse(TimSort.java:426) at java.util.TimSort.sort(TimSort.java:223) 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 jenkins.advancedqueue.sorter.AdvancedQueueSorter.sortBuildableItems(AdvancedQueueSorter.java:81) at hudson.model.Queue.maintain(Queue.java:1021) at hudson.model.Queue$MaintainTask.doRun(Queue.java:1994) at hudson.triggers.SafeTimerTask.run(SafeTimerTask.java:54) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.j ava:178) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293 ) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) {noformat} The call to sortBuildableItems() calls the java.utils.Collections.sort() which had a change semantics from Java 6 to 7. Specifically there is a [contract constraint|https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html#compare%28T,%20T%29] in compare() that requires that {{sgn(compare(x, y)) == -sgn(compare(y, x))}} for all {{x}} and {{y}}. Since any two calls to getInQueueSince() will return different values for any BuildableItem object, it's possible that while the signs maybe the same, the absolute values are not and the exception is thrown. {code:java} // Sort Collections.sort(items, new Comparator<BuildableItem>() { public int compare(BuildableItem o1, BuildableItem o2) { float o1weight = getCalculatedWeight(o1); float o2weight = getCalculatedWeight(o2); if (o1weight > o2weight) { return 1; } if (o1weight < o2weight) { return -1; } return (int) (o1.getInQueueSince() - o2.getInQueueSince()); } }); {code} There is a workaround by disabling timsort and reverting to the Java 6's mergesort using {{-Djava.util.Arrays.useLegacyMergeSort=true}}. The problem longterm is that the legacy sorting algorithm might go away in a future release of Java. Recommend changing the subtraction operation to a set of comparisons instead.

    Jenkins JIRA | 2 years ago | Charles Stephens
    java.lang.IllegalArgumentException: Comparison method violates its general contract!
  4. Speed up your debug routine!

    Automated exception search integrated into your IDE

  5. 0

    Internal Comparator violates its general contract

    GitHub | 2 years ago | sobolk
    java.lang.IllegalArgumentException: Comparison method violates its general contract!
  6. 0

    Routed Request Pipe - Internal server error

    GitHub | 3 years ago | TheAndrey
    java.lang.IllegalArgumentException: Comparison method violates its general contract!

    15 unregistered visitors
    Not finding the right solution?
    Take a tour to get the most out of Samebug.

    Tired of useless tips?

    Automated exception search integrated into your IDE

    Root Cause Analysis

    1. java.lang.IllegalArgumentException

      Comparison method violates its general contract!

      at java.util.TimSort.mergeHi()
    2. Java RT
      Collections.sort
      1. java.util.TimSort.mergeHi(TimSort.java:868)
      2. java.util.TimSort.mergeAt(TimSort.java:485)
      3. java.util.TimSort.mergeForceCollapse(TimSort.java:426)
      4. java.util.TimSort.sort(TimSort.java:223)
      5. java.util.TimSort.sort(TimSort.java:173)
      6. java.util.Arrays.sort(Arrays.java:659)
      7. java.util.Collections.sort(Collections.java:217)
      7 frames
    3. jenkins.advancedqueue.sorter
      AdvancedQueueSorter.sortBuildableItems
      1. jenkins.advancedqueue.sorter.AdvancedQueueSorter.sortBuildableItems(AdvancedQueueSorter.java:81)
      1 frame
    4. Hudson
      SafeTimerTask.run
      1. hudson.model.Queue.maintain(Queue.java:1021)
      2. hudson.model.Queue$MaintainTask.doRun(Queue.java:1994)
      3. hudson.triggers.SafeTimerTask.run(SafeTimerTask.java:54)
      3 frames
    5. Java RT
      Thread.run
      1. java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
      2. java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
      3. java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
      4. java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
      5. java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
      6. java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
      7. java.lang.Thread.run(Thread.java:745)
      7 frames