"Comparison method violates its general contract!" - TimSort and GridLayout

Report my findings:

-Djava.util.Arrays.useLegacyMergeSort=true

works

but

System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");

does not work.

It is due to the fact that in JDK Arrays.class

 static final class LegacyMergeSort {
    private static final boolean userRequested = ...

It is a static variable which is defined when jvm starts. Setting System property in the program will have no effect if the class has been loaded into jvm.

I have beeing monitoring the LegacyMergeSort.userRequested variable, and the findings confirmed with above statement.

Update: The program must set system properties before java.util.Arrays is loaded to classloader. Otherwise, once it is loaded, setting the properties is not going to be useful due to the reason mentioned above.

Make sure nothing else loaded Arrays.class:

By putting following code to your program to test:

    java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass", new Class[] { String.class });
    m.setAccessible(true);
    ClassLoader cl = ClassLoader.getSystemClassLoader();
    Object test1 = m.invoke(cl, "java.util.Arrays");
    System.out.println("test1 loaded? ->" + (test1 != null));

It seems to me like you've hit a bug in the JDK since the error seems to come from Swing classes.

Options:

  1. Define the property java.util.Arrays.useLegacyMergeSort as true. Either using in your code the line

    System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
    

    before any Swing code. As the first line in the main method should work.

    Or adding

    -Djava.util.Arrays.useLegacyMergeSort=true
    

    to your starting options (in the console, or in the project properties in an IDE, Ant script, etc.)

  2. Upgrade your JDK and see if the problem goes away

  3. Downgrade to Java 6