JDK-7173464 : Clipboard.getAvailableDataFlavors: Comparison method violates contract
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 7
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_7
  • CPU: x86
  • Submitted: 2012-06-01
  • Updated: 2014-09-15
  • Resolved: 2013-08-14
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8
7u60Fixed 8 b105Fixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.7.0_04"
Java(TM) SE Runtime Environment (build 1.7.0_04-b22)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

EXTRA RELEVANT SYSTEM CONFIGURATION :
MS Office Home and Business 2010
MS Outlook Version 14.0.6112.5000 32 bit

A DESCRIPTION OF THE PROBLEM :
After coping text from MS Outlook email, calling Clipboard.getAvailableDataFlavors() sometimes causes an IllegalArgumentException indicating a incorrect comparator used to sort the DataFlavors.
The below program sometimes prints the flavors correctly, sometimes it stops with the exception.

I've included the mime types when it succeeds in the expected results field. It looks like it has been reported without due to request 7108946 (but the actual bug not public I guess, since I can't find it)

REGRESSION.  Last worked in version 6u31

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
-Copy some text from MS Outlook (HTML e-mail but with just text)
-run the Java program below

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -

Flavors (56):application/x-java-text-encoding; class="[B"text/html; class=java.i
o.Reader; charset=Unicodetext/html; class=java.lang.String; charset=Unicodetext/
html; class=java.nio.CharBuffer; charset=Unicodetext/html; class="[C"; charset=U
nicodetext/html; class=java.io.InputStream; charset=UTF-16text/html; class=java.
nio.ByteBuffer; charset=UTF-16text/html; class="[B"; charset=UTF-16text/html; cl
ass=java.io.InputStream; charset=UTF-8text/html; class=java.nio.ByteBuffer; char
set=UTF-8text/html; class="[B"; charset=UTF-8text/html; class=java.io.InputStrea
m; charset=UTF-16BEtext/html; class=java.nio.ByteBuffer; charset=UTF-16BEtext/ht
ml; class="[B"; charset=UTF-16BEtext/html; class=java.io.InputStream; charset=UT
F-16LEtext/html; class=java.nio.ByteBuffer; charset=UTF-16LEtext/html; class="[B
"; charset=UTF-16LEtext/html; class=java.io.InputStream; charset=ISO-8859-1text/
html; class=java.nio.ByteBuffer; charset=ISO-8859-1text/html; class="[B"; charse
t=ISO-8859-1text/html; class=java.io.InputStream; charset=windows-1252text/html;
 class=java.nio.ByteBuffer; charset=windows-1252text/html; class="[B"; charset=w
indows-1252text/html; class=java.io.InputStream; charset=US-ASCIItext/html; clas
s=java.nio.ByteBuffer; charset=US-ASCIItext/html; class="[B"; charset=US-ASCIIte
xt/rtf; class=java.io.InputStreamtext/rtf; class=java.nio.ByteBuffertext/rtf; cl
ass="[B"application/x-java-serialized-object; class=java.lang.Stringtext/plain;
class=java.io.Reader; charset=Unicodetext/plain; class=java.lang.String; charset
=Unicodetext/plain; class=java.nio.CharBuffer; charset=Unicodetext/plain; class=
"[C"; charset=Unicodetext/plain; class=java.io.InputStream; charset=unicodetext/
plain; class=java.nio.ByteBuffer; charset=UTF-16text/plain; class="[B"; charset=
UTF-16text/plain; class=java.io.InputStream; charset=UTF-8text/plain; class=java
.nio.ByteBuffer; charset=UTF-8text/plain; class="[B"; charset=UTF-8text/plain; c
lass=java.io.InputStream; charset=UTF-16BEtext/plain; class=java.nio.ByteBuffer;
 charset=UTF-16BEtext/plain; class="[B"; charset=UTF-16BEtext/plain; class=java.
io.InputStream; charset=UTF-16LEtext/plain; class=java.nio.ByteBuffer; charset=U
TF-16LEtext/plain; class="[B"; charset=UTF-16LEtext/plain; class=java.io.InputSt
ream; charset=ISO-8859-1text/plain; class=java.nio.ByteBuffer; charset=ISO-8859-
1text/plain; class="[B"; charset=ISO-8859-1text/plain; class=java.io.InputStream
; charset=windows-1252text/plain; class=java.nio.ByteBuffer; charset=windows-125
2text/plain; class="[B"; charset=windows-1252text/plain; class=java.io.InputStre
am; charset=US-ASCIItext/plain; class=java.nio.ByteBuffer; charset=US-ASCIIimage
/x-java-image; class=java.awt.Imagetext/plain; class="[B"; charset=US-ASCII
ACTUAL -
Exception in thread "main" java.lang.IllegalArgumentException: Comparison method
 violates its general contract!
        at java.util.TimSort.mergeLo(Unknown Source)
        at java.util.TimSort.mergeAt(Unknown Source)
        at java.util.TimSort.mergeCollapse(Unknown Source)
        at java.util.TimSort.sort(Unknown Source)
        at java.util.TimSort.sort(Unknown Source)
        at java.util.Arrays.sort(Unknown Source)
        at sun.awt.datatransfer.DataTransferer.setToSortedDataFlavorArray(Unknow
n Source)
        at sun.awt.datatransfer.DataTransferer.getFlavorsForFormatsAsArray(Unkno
wn Source)
        at sun.awt.datatransfer.SunClipboard.getAvailableDataFlavors(Unknown Sou
rce)
        at TestDataFlavorComparator.main(TestDataFlavorComparator.java:18)

REPRODUCIBILITY :
This bug can be reproduced often.

---------- BEGIN SOURCE ----------
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;


public class TestGetAvailableDataFlavors {

    public static void main(String[] args) {
        DataFlavor[] flavors = Toolkit.getDefaultToolkit().getSystemClipboard().getAvailableDataFlavors();
        System.out.print("Flavors (" + flavors.length + "):");
        for(DataFlavor flavor : flavors) {
            System.out.print(flavor.getMimeType());
        }
        System.out.println();
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Use the -Djava.util.Arrays.useLegacyMergeSort=true command line option to disable the Java 7 sort

Comments
I have removed the noreg-dev-issue label, because the changeset for this bug contains a regression test with a valid @bug tag. Probably the label was added by mistake.
06-09-2013

It is about JDK 7 migration and request the same fix back port to 7u releases.
08-08-2013

CAP member's customers have done the transition to JDK 7 and they still have this issue. They believe this report is very good, including a test case and the provided trace clearly indicates a bug in the jdk class "sun.awt.datatransfer.DataTransferer". And think that the report is classified as duplicate to JDK-7193557 which is obviously wrong (there the custom comparator is buggy, here the internal class "sun.awt.datatransfer.DataTransferer $DataFlavorComparator" is buggy). Currently workaround is to set the property "java.util.Arrays.useLegacyMergeSort " to true, which is not desired and may have no effect with JDK8.
05-08-2013