简体   繁体   English

错误:java.lang.IllegalArgumentException:即使使用替代方法,比较方法也违反了其常规协定

[英]Error: java.lang.IllegalArgumentException: Comparison method violates its general contract even using workaround

I have already spent two days to short out this error, even I tried workaround which are suggested in several stackoverflow posts "-Djava.util.Arrays.useLegacyMergeSort=true" but it also doesnt work. 我已经花了两天时间来解决此错误,即使我尝试了一些在stackoverflow帖子“ -Djava.util.Arrays.useLegacyMergeSort = true”中建议的解决方法,也无法正常工作。

this is the details of my command and its returning error: 这是我的命令及其返回错误的详细信息:

Command: 命令:

hadoop jar CloudBrush.jar -Djava.awt.headless=true -Djava.util.Arrays.useLegacyMergeSort=true -reads /Ec10k -asm Ec10k_Brush -k 21 -readlen 36

Error: 错误:

    Error: java.lang.IllegalArgumentException: Comparison method violates its general contract!
    at java.util.TimSort.mergeHi(TimSort.java:895)
    at java.util.TimSort.mergeAt(TimSort.java:512)
    at java.util.TimSort.mergeCollapse(TimSort.java:437)
    at java.util.TimSort.sort(TimSort.java:241)
    at java.util.Arrays.sort(Arrays.java:1512)
    at java.util.ArrayList.sort(ArrayList.java:1454)
    at java.util.Collections.sort(Collections.java:175)
    at Brush.VerifyOverlap$VerifyOverlapReducer.reduce(VerifyOverlap.java:252)
    at Brush.VerifyOverlap$VerifyOverlapReducer.reduce(VerifyOverlap.java:1)
    at org.apache.hadoop.mapred.ReduceTask.runOldReducer(ReduceTask.java:444)
    at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:392)
    at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:163)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:422)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1628)
    at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158)

Exception in thread "main" java.io.IOException: Job failed!
    at org.apache.hadoop.mapred.JobClient.runJob(JobClient.java:836)
    at Brush.VerifyOverlap.run(VerifyOverlap.java:381)
    at Brush.BrushAssembler.buildOverlap(BrushAssembler.java:326)
    at Brush.BrushAssembler.run(BrushAssembler.java:838)
    at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
    at Brush.BrushAssembler.main(BrushAssembler.java:913)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.hadoop.util.RunJar.run(RunJar.java:221)
    at org.apache.hadoop.util.RunJar.main(RunJar.java:136)

This is the Comparator : 这是Comparator

    class OvelapSizeComparator implements Comparator {
        public int compare(Object element1, Object element2) {
            OverlapInfo obj1 = (OverlapInfo) element1;
            OverlapInfo obj2 = (OverlapInfo) element2;
            if ((int)(obj1.overlap_size - obj2.overlap_size) >= 0) {
                return -1;
            } else {
                return 1;
            }
        }
    }

The real problem is that your OvelapSizeComparator [ sic ] is defective. 真正的问题是您的OvelapSizeComparator [ sic ]有缺陷。 If the two objects' overlap_size values are equal, it returns -1 when it should return 0 . 如果两个对象的overlap_size值相等,则应返回0时返回-1 And if they're not equal, it returns a value with the incorrect sign. 如果它们不相等,则返回带有错误符号的值。

To fix it, replace this: 要修复它,请替换为:

if ((int)(obj1.overlap_size - obj2.overlap_size) >= 0) {
   return -1;
} else {
   return 1;
}

...with this: ...有了这个:

return obj1.overlap_size - obj2.overlap_size;

I got the error fixed. 我已修复错误。 I thought it was problem with Hadoop, I was wrong. 我以为是Hadoop的问题,我错了。 It is a problem with Java version. Java版本有问题。 We also upgraded Java version along with Hadoop. 我们还与Hadoop一起升级了Java版本。 Arrays.sort() method of java 7 and java 8 uses TimSort if the number of elements to be sorted are more than 32. And Tim sort enforces strict transitive property in comparing. 如果要排序的元素数大于32,则Java 7和Java 8的Arrays.sort()方法将使用TimSort。Timsort在比较中强制使用严格的传递属性。

If ((compare(x, y)>0) && (compare(y, z)>0)) then compare(x, z) should be greater than 0. Else "java.lang.IllegalArgumentException: Comparison method violates its general contract" error is thrown. 如果(((compare(x,y)> 0)&&(compare(y,z)> 0))则compare(x,z)应该大于0。否则“ java.lang.IllegalArgumentException:比较方法违反了它的一般性合同”错误。

Either you should change your compare method to be consistent with transitive property or use older version sort by setting "java.util.Arrays.useLegacyMergeSort" to true for "Map Task Java Opts Base" or "Reduce Task Java Opts Base" and it then should apply to all the JVM's started for map or reduce. 您应该通过将“ Map Task Java Opts Base”或“ Reduce Task Java Opts Base”设置为“ java.util.Arrays.useLegacyMergeSort”为true来更改比较方法,使其与传递属性一致,或者使用较旧的版本排序,然后应该适用于所有JVM启动的map或reduce。

For 2.6.0-cdh5.4.2 Haddop you can add this setting to map task by adding 对于2.6.0-cdh5.4.2 Haddop,您可以通过添加以下设置将此设置添加到地图任务

-D mapreduce.map.java.opts= "-Djava.util.Arrays.useLegacyMergeSort=true" -D mapreduce.map.java.opts =“ -Djava.util.Arrays.useLegacyMergeSort = true”
-D mapreduce.reduce.java.opts= "-Djava.util.Arrays.useLegacyMergeSort=true" -D mapreduce.reduce.java.opts =“ -Djava.util.Arrays.useLegacyMergeSort = true”

or via code 或通过代码

job.getConfiguration().set("mapreduce.map.java.opts","-Djava.util.Arrays.useLegacyMergeSort=true"); job.getConfiguration()。set(“ mapreduce.map.java.opts”,“-Djava.util.Arrays.useLegacyMergeSort = true”);

job.getConfiguration().set("mapreduce.reduce.java.opts","-Djava.util.Arrays.useLegacyMergeSort=true"); job.getConfiguration()。set(“ mapreduce.reduce.java.opts”,“-Djava.util.Arrays.useLegacyMergeSort = true”);

You can reproduce this error by running the main method in Test.java code on JVM 7 or later versions. 您可以通过在JVM 7或更高版本上的Test.java代码中运行main方法来重现此错误。 To summarize what this code does. 总结一下这段代码的作用。 This code tries to sort 40 person objects with a compare method which does not hold transitive property 此代码尝试使用不具有传递属性的compare方法对40个人进行排序

//Person.java //Person.java

public class Person implements Comparable{ 公共类人员实现可比{

public String name;
public int age ;
public int salary;

@Override
public int compareTo(Person o) {
    if(o instanceof Person){
        int ret=0;
        if(age == 25 && ((Person)o).age ==27) ret = 1;
        else if(age == 27 && ((Person)o).age ==29) ret = 1;
        else if(age == 25 && ((Person)o).age ==29) ret = -1;
        else{
                if( age < ((Person)o).age) ret = -1;
                if(age > ((Person)o).age) ret = 1;
                if(salary < ((Person)o).salary) ret = -1;
                if(salary > ((Person)o).salary) ret = 1;           
        }
        return ret; 

    }
    return 0;
}

@Override
public String toString(){
 return "name="+name+":age="+age+";";     
}

} }

//Test.java //Test.java

import java.util.Arrays; 导入java.util.Arrays;

public class Test { 公开课测试{

public static void main(String args[]) {
    Test t = new Test();
    t.sortPersons(args);        
}

public void sortPersons(String args[]) {        

    Person p1 = new Person();
    p1.age = 25;
    p1.name = "ABC";

    Person p2 = new Person();
    p2.age = 29;
    p2.name = "ABZ";

    Person p3 = new Person();
    p3.age = 27;
    p3.name = "AZ";

    Person p4 = new Person();
    p4.age = 27;
    p4.name = "AZ";

    Person p5 = new Person();
    //p5.age = 22;
    //p5.name="ZZ";

    Person[] p = new Person[40];

    p[0] = p2;
    p[1] = p3;
    p[2] = p4;
    p[3] = p1;
    p[4] = p5;
    for (int i = 1; i < 8; i++) {
        p[i * 5] = p[0];
        p[i * 5 + 1] = p[1];
        p[i * 5 + 2] = p[2];
        p[i * 5 + 3] = p[3];
        p[i * 5 + 4] = p[4];
    }

    System.out.println("\nSortingInput\n");           
    Arrays.sort(p);       
    System.out.println("\nSorting complete\n");
}

} }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 java.lang.IllegalArgumentException:比较方法违反了它的一般约定,在 java7 中给出了错误 - java.lang.IllegalArgumentException: Comparison method violates its general contract giving Error in java7 Java 错误:java.lang.IllegalArgumentException:比较方法违反其一般约定 - Java Error: java.lang.IllegalArgumentException: Comparison method violates its general contract 随机错误-java.lang.IllegalArgumentException:比较方法违反了其一般约定 - Random error - java.lang.IllegalArgumentException: Comparison method violates its general contract Java 7:java.lang.IllegalArgumentException:比较方法违反了其一般合同 - Java 7 : java.lang.IllegalArgumentException: Comparison method violates its general contract Java sort抛出java.lang.IllegalArgumentException:比较方法违反了其一般合同 - Java sort throws java.lang.IllegalArgumentException: Comparison method violates its general contract Java Rest Template throws java.lang.IllegalArgumentException: Comparison method violates its general contract - Java Rest Template throws java.lang.IllegalArgumentException: Comparison method violates its general contract java.lang.IllegalArgumentException:比较方法违反了它的一般约定! 日期 - java.lang.IllegalArgumentException: Comparison method violates its general contract! java.util.Date 为什么我得到这个异常 java.lang.IllegalArgumentException:比较方法违反了它的一般契约 - Why did I get this exception java.lang.IllegalArgumentException: Comparison method violates its general contract 获取java.lang.IllegalArgumentException:比较方法违反了其一般约定! 排序算法应该是100%稳定的 - Getting java.lang.IllegalArgumentException: Comparison method violates its general contract! with a sort algo that should be 100% stable 线程“AWT-EventQueue-0”中的异常java.lang.IllegalArgumentException:比较方法违反了其总契约 - Exception in thread “AWT-EventQueue-0” java.lang.IllegalArgumentException: Comparison method violates its general contract
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM