-
Notifications
You must be signed in to change notification settings - Fork 848
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"Comparison method violates its general contract" on Array.sort() with randomize #255
Comments
I tried this with the code in "master": ./gradlew jar It looks like it works for me. But if you have a specific test case then please attach it. Thanks! |
We are using 1.7R4. It may not trigger on every execution. It depends on the randomization. Can you take a quick look at this method: org.mozilla.javascript.NativeArray.js_sort(NativeArray.java:1024) Thanks! |
It looks like "js_sort" hasn't changed much in many years. But still I can't reproduce this, even if I call the code a few million times in a loop. But if you have any ideas we can keep trying. |
If the problem is consistant, i will put some notes.
On enviroment variable to enforce jvm to use legacy sort algorithm. |
This old, old issue is coming up in other places now! In your example, do you pass a comparator function to "sort"? If not then we have some work to do on the default comparator and how it handles "undefined..." |
As linked in the initial post the code is this: So yes this is a custom comparator. The problem is as follows: Java's sort method has a certain "general contract" about comparators. https://docs.oracle.com/javase/6/docs/api/java/util/Comparator.html That is: if Or this (i'm not 100% sure): (the one above is much more likely)
But with the above (random) comparator this is obviously not the case.
From your statement i can derive that there are other comparators in the wild, that also violate this contract. Now the point is: This is Java's interpretation of how things should be. But in JavaScript there is no such thing. The above random sort code should work in JavaScript. At very least we can see, that the above random sort code works on other JS-engines (like Google Chrome). |
I agree and sorry for reading so fast. The comparator there is not good
code, obviously, but according to the JavaScript spec it should not throw
an exception.
The solution is to replace Arrays.sort with a different sorting algorithm.
Any suggestions on which one would be best?
In the meantime, I created a new PR that does two things: Makes doubly-sure
that the default case (non-comparator) does not behave badly, and throws a
proper JavaScript exception instead of IllegalArgumentException. I'd
appreciate a look before I merge it!
#311
…On Fri, Jul 28, 2017 at 1:06 AM, Finomosec ***@***.***> wrote:
As linked in the initial post the code is this:
[1,2,3,4,5,6].sort(function() { return .5 - Math.random(); });
So yes this is a custom comparator.
The problem is as follows:
Java's sort method has a certain "general contract" about comparators.
https://docs.oracle.com/javase/6/docs/api/java/util/Comparator.html
That is: if a < b and b < c then a < c
Or this (i'm not 100% sure): (the one above is much more likely)
The ordering imposed by a comparator c on a set of elements S is said to
be consistent with equals if and only if c.compare(e1, e2)==0 has the same
boolean value as e1.equals(e2) for every e1 and e2 in S.
But with the above (random) comparator this is obviously not the case.
This old, old issue is coming up in other places now!
From your statement i can derive that there are other comparators in the
wild, that also violate this contract.
Now the point is: This is Java's interpretation of how things should be.
But in JavaScript there is no such thing. The above random sort code
should work in JavaScript.
So the bug IMHO is using using Java's sort method in the first place.
It might have been convenient, but it is not consistent with standard
JavaScript:
https://www.w3schools.com/jsref/jsref_sort.asp
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#255 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAf0a3JwbqiRw1GJ9KTHmWHz_2jHXS6jks5sSZaXgaJpZM4GkD2x>
.
|
Can we close this since #311 was merged? |
Array.sort now uses a custom sort method that will happily sort things according to whatever crazy ordering the caller provides. |
I have a solution, when I want to sort numbers and an array element is null, then I put 0, and the error disappears, is needed to care that the size of each row in the bidimensional arrays must be the same |
@Finomosec Thanks for your answer. |
Here: http://stackoverflow.com/a/18650169
Someone demonstrates how to use the Array.sort() function to randomize an array.
Which made it very hard to find the cause of it.
We are using interpreted mode here.
Can you adjust the error-handling of this case (or maybe in general for all similar cases) so that the Exception is properly wrapped in a JavaScriptException with the proper JS-stacktrace?
Greetings Fred;
The text was updated successfully, but these errors were encountered: