United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-7173464 : Clipboard.getAvailableDataFlavors: Comparison method violates contract

Details
Type:
Bug
Submit Date:
2012-06-01
Status:
Resolved
Updated Date:
2014-02-12
Project Name:
JDK
Resolved Date:
2013-08-14
Component:
client-libs
OS:
windows_7
Sub-Component:
java.awt
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:

Related Reports
Backport:
Backport:
Relates:
Relates:

Sub Tasks

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.
                                     
2013-09-06
URL:   http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/1d6ce0070fd3
User:  lana
Date:  2013-08-26 18:32:19 +0000

                                     
2013-08-26
URL:   http://hg.openjdk.java.net/jdk8/awt/jdk/rev/1d6ce0070fd3
User:  pchelko
Date:  2013-08-14 13:20:46 +0000

                                     
2013-08-14
It is about JDK 7 migration and request the same fix back port to 7u releases.
                                     
2013-08-08
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.

                                     
2013-08-05



Hardware and Software, Engineered to Work Together