2012-11-26 30 views
37

मैंने इसमें जेपीनल और जेएलएबल सरणी के साथ एक रंग पैलेट बनाया है। सबसे पहले यह अच्छी तरह से काम किया, लेकिन फिर मैंने जेपीनेल से कुछ अन्य जेएलएबल्स लगाए और उन्हें कुछ घटनाएं जोड़ दीं।"तुलना विधि अपने सामान्य अनुबंध का उल्लंघन करती है!" - टिमॉर्ट और ग्रिडलाउट

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Comparison method violates its general contract! 
at java.util.TimSort.mergeLo(TimSort.java:747) 
at java.util.TimSort.mergeAt(TimSort.java:483) 
at java.util.TimSort.mergeCollapse(TimSort.java:410) 
at java.util.TimSort.sort(TimSort.java:214) 
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 javax.swing.SortingFocusTraversalPolicy.enumerateAndSortCycle(SortingFocusTraversalPolicy.java:136) 
at javax.swing.SortingFocusTraversalPolicy.getFocusTraversalCycle(SortingFocusTraversalPolicy.java:110) 
at javax.swing.SortingFocusTraversalPolicy.getFirstComponent(SortingFocusTraversalPolicy.java:435) 
at javax.swing.LayoutFocusTraversalPolicy.getFirstComponent(LayoutFocusTraversalPolicy.java:166) 
at javax.swing.SortingFocusTraversalPolicy.getDefaultComponent(SortingFocusTraversalPolicy.java:515) 
at java.awt.FocusTraversalPolicy.getInitialComponent(FocusTraversalPolicy.java:169) 
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:380) 
at java.awt.Component.dispatchEventImpl(Component.java:4731) 
at java.awt.Container.dispatchEventImpl(Container.java:2287) 
at java.awt.Window.dispatchEventImpl(Window.java:2719) 
at java.awt.Component.dispatchEvent(Component.java:4687) 
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:723) 
at java.awt.EventQueue.access$200(EventQueue.java:103) 
at java.awt.EventQueue$3.run(EventQueue.java:682) 
at java.awt.EventQueue$3.run(EventQueue.java:680) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87) 
at java.awt.EventQueue$4.run(EventQueue.java:696) 
at java.awt.EventQueue$4.run(EventQueue.java:694) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
at java.awt.EventQueue.dispatchEvent(EventQueue.java:693) 
at java.awt.SequencedEvent.dispatch(SequencedEvent.java:116) 
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:721) 
at java.awt.EventQueue.access$200(EventQueue.java:103) 
at java.awt.EventQueue$3.run(EventQueue.java:682) 
at java.awt.EventQueue$3.run(EventQueue.java:680) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87) 
at java.awt.EventQueue$4.run(EventQueue.java:696) 
at java.awt.EventQueue$4.run(EventQueue.java:694) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
at java.awt.EventQueue.dispatchEvent(EventQueue.java:693) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244) 
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139) 
at java.awt.EventDispatchThread.run(EventDispatchThread.java:97) 

मैं सब कुछ मैं पहली बार मैं यह त्रुटि आई के बाद किया है दूर करने के लिए, लेकिन अभी भी यह हो रही रखने की कोशिश की: अब मैं इस त्रुटि प्राप्त हो रही। जब मैं ग्रिडलाउट से लेआउट को किसी और चीज़ में बदलता हूं, तो त्रुटि गायब हो जाती है, लेकिन कोड बेकार हो जाता है। तो मुझे ग्रिडलाउट की आवश्यकता है। जब मैं उस जेपीनेल में सबकुछ किसी अन्य जेपीनेल में ले जाता हूं, तो त्रुटि भी दूर हो जाती है। लेकिन जब मैं पहली जेपीनल हटा देता हूं, तो त्रुटि वापस आती है।

वैसे, कार्यक्रम काम करता है, लेकिन यह हो रही त्रुटियों रखने के लिए pleasent नहीं है ...

संपादित करें: जब मैं कम से कम 225 रंग का उपयोग, वहाँ कोई त्रुटि है। मैं क्या हो रहा है के बारे में वास्तव में उत्सुक हूँ। किसी भी स्पष्टीकरण की सराहना की जाएगी ...

+0

इसे देखें: http://stackoverflow.com/questions/7849539/comparison-method-violates-its- सामान्य-contract-java-7- केवल – mbelow

+1

ध्यान दें कि यह एक बग नहीं है, लेकिन एक छेड़छाड़ को हटाने । छेड़छाड़ यह थी कि सरणी को सॉर्ट करने के लिए इस्तेमाल किए गए तुलनित्र में एक ज्ञात तर्क त्रुटि हो सकती है। जावा 7 के साथ एक चेक जोड़ा गया है, और यह जांच अब इस त्रुटि को आउटपुट करती है अगर तुलनित्र का गलत व्यवहार होता है। चूंकि यह समस्याएं पैदा कर सकता है (हालांकि यह अन्य हल करता है), जावा 7 में पिछली विधि (कोई तुलनात्मक सत्यापन नहीं) का उपयोग करने के लिए सरणी को मजबूर करने के लिए एक संपत्ति शामिल है। इस संदेश को जावा की नई रिलीज के साथ गायब होने की उम्मीद न करें। लाइब्रेरी डेवलपर्स को इसे अपने कोड में ठीक करना होगा। – mins

उत्तर

42

ऐसा लगता है जैसे आपने bug in the JDK मारा है क्योंकि त्रुटि स्विंग कक्षाओं से आती है।

विकल्प:

  1. true के रूप में संपत्ति java.util.Arrays.useLegacyMergeSort को परिभाषित करें। या तो अपने कोड में उपयोग

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

    किसी भी स्विंग कोड से पहले। main विधि में पहली पंक्ति के रूप में कार्य करना चाहिए।

    या

  2. अपने JDK अपग्रेड करें और समस्या है, तो देखते हैं (एक IDE, चींटी स्क्रिप्ट, आदि में कंसोल में, या परियोजना संपत्तियों में)

    -Djava.util.Arrays.useLegacyMergeSort=true 
    
    आपके प्रारंभ विकल्प के लिए

    जोड़ने दूर जावा से 6

  3. डाउनग्रेड चला जाता है
+0

मुझे असभ्य ब्रायन की तरह लगता है। मैं जावा के लिए बस नया हूं और तुरंत एक बग मारा। क्या आप मुझे समझा सकते हैं, मैं अपने ऐप को "-Djava.util.Arrays.useLegacyMergeSort = true" के साथ कैसे चला रहा हूं ... –

+0

यह निर्भर है कि आप अपना आवेदन कैसे चला रहे हैं। कमांड लाइन? नेटबीन, ग्रहण या कुछ अन्य आईडीई? – madth3

+5

एक सामान्य विकल्प 'System.setProperty ("java.util.Arrays.useLegacyMergeSort", "true") को जोड़ना होगा; 'आपकी' मुख्य 'विधि में पहली पंक्ति के रूप में। – madth3

13

मेरी निष्कर्ष रिपोर्ट:

-Djava.util.Arrays.useLegacyMergeSort=true 

काम करता है

लेकिन

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

काम नहीं करता।

यह तथ्य यह है कि JDK Arrays.class

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

में यह एक स्थिर चर जो जब JVM शुरू होता है परिभाषित किया जाता है के कारण है। कार्यक्रम में सिस्टम प्रॉपर्टी सेट करना कोई प्रभाव नहीं होगा यदि कक्षा jvm में लोड हो गई है।

मुझे लेगेसीमेर्जोर्ट.यूसररक्वेटेड वैरिएबल की निगरानी करने और उपरोक्त कथन के साथ निष्कर्ष निकालने की मधुमक्खी है।

अद्यतन: प्रोग्राम java.util से पहले सिस्टम गुणों को सेट करना होगा। Arrays को क्लासलोडर में लोड किया गया है। अन्यथा, एक बार लोड होने के बाद, गुणों को सेट करना ऊपर उल्लिखित कारणों से उपयोगी नहीं होगा।

यकीन है कि कुछ भी नहीं किसी और Arrays.class लोड करें:

परीक्षण करने के लिए अपने कार्यक्रम के लिए निम्न कोड डाल करके:

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)); 
6

[अपडेट] यह समाधान दुर्भाग्य से समस्या को हल करने की गारंटी नहीं है सभी मामलों में। कीबोर्डफोकसमेनर के डिफ़ॉल्ट सॉर्टिंग फोकस ट्रैवर्सल पॉलिसी को पैच करने के लिए पर्याप्त नहीं है।

मैं अपने अपडेट सहित नीचे रॉबिन लोक्सले द्वारा उत्तर पढ़ने की अनुशंसा करता हूं। [/ अपडेट]

java.lang.IllegalArgumentException: Comparison method violates its general contract! 
    at java.util.TimSort.mergeHi(TimSort.java:868) 

यह समस्या javax.swing.LayoutComparator में एक बग के कारण होता है।

निम्न श्रेणी javax.swing.LayoutComparator का एक निश्चित संस्करण स्थापित करती है, जो Comparator<Component> के अनुबंध का उल्लंघन नहीं करती है। javax.swing.LayoutComparator का यह (या कोई अन्य) निश्चित संस्करण ओरेकल को कुछ ओरेकल योगदानकर्ता द्वारा प्रस्तुत किया जाना चाहिए।

package ...; 

import java.awt.Component; 
import java.awt.ComponentOrientation; 
import java.awt.FocusTraversalPolicy; 
import java.awt.KeyboardFocusManager; 
import java.awt.Window; 
import java.lang.reflect.Field; 
import java.util.Comparator; 
import java.util.LinkedList; 
import java.util.ListIterator; 

import javax.swing.JRootPane; 
import javax.swing.SortingFocusTraversalPolicy; 
import javax.swing.UIManager; 

/** 
* Uses reflection to install a fixed version of {@link javax.swing.LayoutComparator} to solve the 
* LayoutFocusTraversalPolicy/TimSort problem. 
* 
* <p> 
* <code>java.lang.IllegalArgumentException: Comparison method violates its general contract!</code> 
* <br/> 
* &nbsp;&nbsp;&nbsp;&nbsp;{@code  at java.util.TimSort.mergeHi(TimSort.java:868)} 
* </p> 
* <p> 
* Usage: call {@code Class.forName(LayoutFocusTraversalPolicyTimSortBugFixer.class.getName())} 
* before creating Swing components. 
* </p> 
* 
* @author Burkhard Strauss 
* @since Feb 2015 
*/ 
public class LayoutFocusTraversalPolicyTimSortBugFixer 
{ 

    static 
    { 
     UIManager.getUI(new JRootPane()); // make Swing install the SortingFocusTraversalPolicy 
     final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager 
      .getCurrentKeyboardFocusManager(); 
     final FocusTraversalPolicy focusTraversalPolicy = keyboardFocusManager 
      .getDefaultFocusTraversalPolicy(); 
     boolean fixed = false; 
     if (focusTraversalPolicy instanceof SortingFocusTraversalPolicy) 
     { 
     try 
     { 
      final Field field = SortingFocusTraversalPolicy.class.getDeclaredField("comparator"); 
      final boolean accessible = field.isAccessible(); 
      try 
      { 
       field.setAccessible(true); 
       field.set(focusTraversalPolicy, new LayoutComparator()); 
       fixed = true; 
      } 
      finally 
      { 
       field.setAccessible(accessible); 
      } 

     } 
     catch (final Exception e) 
     { 
     } 
     } 
     if (!fixed) 
     { 
     Loggers.getLoggerFor(LayoutFocusTraversalPolicyTimSortBugFixer.class).warn("could not fix the bug"); 
     } 
    } 

    /** 
    * Fixed version of {@link javax.swing.LayoutComparator}. 
    * <p> 
    * Search for 'bugfix' in the code. 
    * </p> 
    * 
    * @author Burkhard Strauss 
    * @since Feb 2015 
    */ 
    @SuppressWarnings("serial") 
    private static class LayoutComparator implements Comparator<Component>, java.io.Serializable 
    { 

     private static final int ROW_TOLERANCE = 10; 

     private boolean horizontal = true; 
     private boolean leftToRight = true; 

     @SuppressWarnings("unused") 
     void setComponentOrientation(final ComponentOrientation orientation) 
     { 
     horizontal = orientation.isHorizontal(); 
     leftToRight = orientation.isLeftToRight(); 
     } 

     @Override 
     public int compare(Component a, Component b) 
     { 
     if (a == b) 
     { 
      return 0; 
     } 

     // Row/Column algorithm only applies to siblings. If 'a' and 'b' 
     // aren't siblings, then we need to find their most inferior 
     // ancestors which share a parent. Compute the ancestory lists for 
     // each Component and then search from the Window down until the 
     // hierarchy branches. 
     if (a.getParent() != b.getParent()) 
     { 
      final LinkedList<Component> aAncestory = new LinkedList<Component>(); 
      for (; a != null; a = a.getParent()) 
      { 
       aAncestory.add(a); 
       if (a instanceof Window) 
       { 
        break; 
       } 
      } 
      if (a == null) 
      { 
       // 'a' is not part of a Window hierarchy. Can't cope. 
       throw new ClassCastException(); 
      } 
      final LinkedList<Component> bAncestory = new LinkedList<Component>(); 
      for (; b != null; b = b.getParent()) 
      { 
       bAncestory.add(b); 
       if (b instanceof Window) 
       { 
        break; 
       } 
      } 
      if (b == null) 
      { 
       // 'b' is not part of a Window hierarchy. Can't cope. 
       throw new ClassCastException(); 
      } 
      for (ListIterator<Component> aIter = aAncestory.listIterator(aAncestory.size()), bIter = bAncestory 
        .listIterator(bAncestory.size());;) 
      { 
       if (aIter.hasPrevious()) 
       { 
        a = aIter.previous(); 
       } 
       else 
       { 
        // a is an ancestor of b 
        return -1; 
       } 
       if (bIter.hasPrevious()) 
       { 
        b = bIter.previous(); 
       } 
       else 
       { 
        // b is an ancestor of a 
        return 1; 
       } 
       if (a != b) 
       { 
        break; 
       } 
      } 
     } 

     final int ax = a.getX(), ay = a.getY(), bx = b.getX(), by = b.getY(); 
     int zOrder = a.getParent().getComponentZOrder(a) - b.getParent().getComponentZOrder(b); 
     { 
      // 
      // Here is the bugfix: 
      // Don't return 0 if a != b. This would violate the contract of 
      // Comparator<Component>.compare(). 
      // 
      if (zOrder == 0) 
      { 
       zOrder = -1; 
      } 
     } 
     if (horizontal) 
     { 
      if (leftToRight) 
      { 

       // LT - Western Europe (optional for Japanese, Chinese, Korean) 

       if (Math.abs(ay - by) < ROW_TOLERANCE) 
       { 
        return (ax < bx) ? -1 : ((ax > bx) ? 1 : zOrder); 
       } 
       else 
       { 
        return (ay < by) ? -1 : 1; 
       } 
      } 
      else 
      { // !leftToRight 

       // RT - Middle East (Arabic, Hebrew) 

       if (Math.abs(ay - by) < ROW_TOLERANCE) 
       { 
        return (ax > bx) ? -1 : ((ax < bx) ? 1 : zOrder); 
       } 
       else 
       { 
        return (ay < by) ? -1 : 1; 
       } 
      } 
     } 
     else 
     { // !horizontal 
      if (leftToRight) 
      { 

       // TL - Mongolian 

       if (Math.abs(ax - bx) < ROW_TOLERANCE) 
       { 
        return (ay < by) ? -1 : ((ay > by) ? 1 : zOrder); 
       } 
       else 
       { 
        return (ax < bx) ? -1 : 1; 
       } 
      } 
      else 
      { // !leftToRight 

       // TR - Japanese, Chinese, Korean 

       if (Math.abs(ax - bx) < ROW_TOLERANCE) 
       { 
        return (ay < by) ? -1 : ((ay > by) ? 1 : zOrder); 
       } 
       else 
       { 
        return (ax > bx) ? -1 : 1; 
       } 
      } 
     } 
     } 
    } 
} 
3

मैं सिर्फ एक ही त्रुटि का सामना किया है और यह ट्रैकिंग नीचे समय की एक अच्छी रकम खर्च किए। इस त्रुटि में भाग लेने वाले अन्य लोगों की सहायता के लिए टिमसॉर्ट का परीक्षण करना महत्वपूर्ण है। चेक जो ट्रांजिटिविटी अनुबंध का उल्लंघन करते हैं और इस त्रुटि को फेंकते हैं, एल्गोरिदम में गहरे होते हैं और इस समस्या को पुन: उत्पन्न करने से पहले कुछ मानदंडों को पूरा करने के लिए एक परीक्षण की आवश्यकता होती है।

  1. 32 या अधिक ऑब्जेक्ट्स वाली एक सूची बनाएं।
  2. उस सूची में, दो या अधिक रनों की आवश्यकता है।
  3. प्रत्येक रन में 3 या अधिक ऑब्जेक्ट्स होनी चाहिए।

एक बार जब आप उन दो मानदंडों को पूरा कर लेंगे तो आप इस विफलता के लिए परीक्षण शुरू कर सकते हैं।

एक रन को सूची के उप-सेट के रूप में परिभाषित किया जाता है जहां प्रत्येक आइटम वांछित आदेशित स्थिति में पहले से ही होता है।

0

ऊपर ले जाने के रूप में लेआउटकंपेटर को पैच करने के लिए पर्याप्त नहीं है। यह फिक्स मेरे मामले में काम नहीं करता है। मुद्दा जेडीके 8 (कम से कम 8u45) में तय किया गया था। सॉर्टिंग फोकस ट्रैवर्सल पॉलिसी विरासत मर्ज सॉर्ट विधि का उपयोग करने के लिए।