17

I'm wondering if I compile in Java 6, but someone runs the program on Java 7, will the Java 6 or 7 version of Arrays.sort be used?

It's important because the new mergesort throws an IllegalArgumentException, and the old one doesn't (see Comparison method violates its general contract! Java 7 only)

Now, it's possible to compile in Java 7 using Arrays.useLegacyMergeSort, but obviously that flag isn't available for Java 6 - and we want to be compatible on Mac OS Snow Leopard (which uses 6).

For some reason (see http://madbean.com/2006/target14/) the -target compiler flag doesn't seem to produce compatible code, so we'd rather compile in Java 6.

Any suggestions?

Community
  • 1
  • 1
Alex
  • 18,332
  • 10
  • 49
  • 53
  • 8
    The `java.util.Arrays.useLegacyMergeSort` property is specified at runtime, not compile. What problems are you having when you use it with a Java 6 VM? – Perception Apr 09 '13 at 04:56
  • You will use the version 7 on a version 7 JVM even if you compile against version 6. Just set the System property then you will always use the version 6 sort. – BevynQ Apr 09 '13 at 04:59
  • 3
    @Alex: if the new mergesort throws an IAE, that's because your code is wrong, whether it's running in Java 6 or Java 7. What you should be doing is fixing that issue, at which point your code will run the same in both environments. – Louis Wasserman Apr 09 '13 at 14:50
  • @LouisWasserman: Well, yes and no! If the code does what it's intended to do, and is readable and maintainable, is it really a problem whether or not it satisfies this apparent contract? – Alex Apr 10 '13 at 08:17
  • I guess we'll have to agree to disagree on that one, then. – Alex Apr 11 '13 at 02:45
  • 1
    @Alex That is the point of contracts: You can only be sure that the other side fulfills its promises if you do so, too. Previously, it fulfilled it (or seemed to do so – I suppose the could be inconsistent results before) even if you didn't, but this changed now for a better implementation. – Paŭlo Ebermann Apr 11 '13 at 20:01
  • Well, the code works, and is readable and maintainable... in the end, that's the bottom line. – Alex Apr 12 '13 at 02:04
  • @Alex Well, doesn't it throw an `IllegalArgumentException` when you try to use your code with a compliant sort implementation? I'd label your code _not working_ then. Remember that tis way, you can't know wether your code will work when run with a different JRE. – Feuermurmel Jan 06 '14 at 15:56
  • @Alex You might thinmk that your code works. We had such a case in our company too. The programmer implemented a wrong compare method, and two years later when another used that code in an extension of the project, the sorting failed, and he said "java does not sort correctly". So fix your compare / equals and hashcode – AlexWien Jul 11 '14 at 13:28

1 Answers1

19

try to set system property

java -Djava.util.Arrays.useLegacyMergeSort=true ...

Note that it's not from Arrays public API but from src

   /**
     * Old merge sort implementation can be selected (for
     * compatibility with broken comparators) using a system property.
     * Cannot be a static boolean in the enclosing class due to
     * circular dependencies. To be removed in a future release.
     */
    static final class LegacyMergeSort {
        private static final boolean userRequested =
            java.security.AccessController.doPrivileged(
                new sun.security.action.GetBooleanAction(
                    "java.util.Arrays.useLegacyMergeSort")).booleanValue();
    }
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • Ah, oops! I thought it was an alternative method, not a flag... so the java 7 user will run something like java -jar -Djava.util.Arrays.useLegacyMergeSort=true Program.jar , is that right? – Alex Apr 09 '13 at 05:04
  • rather java -Djava.util.Arrays.useLegacyMergeSort=true -jar Program.jar – Evgeniy Dorofeev Apr 09 '13 at 05:20