ADDITIONAL SYSTEM INFORMATION :
We've seen the crash on Windows 10 and macOS 10.13
A DESCRIPTION OF THE PROBLEM :
We've had this crash multiple times in our application:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:899) ~[?:1.8.0_161]
at java.util.TimSort.mergeAt(TimSort.java:516) ~[?:1.8.0_161]
at java.util.TimSort.mergeForceCollapse(TimSort.java:457) ~[?:1.8.0_161]
at java.util.TimSort.sort(TimSort.java:254) ~[?:1.8.0_161]
at java.util.Arrays.sort(Arrays.java:1512) ~[?:1.8.0_161]
at java.util.ArrayList.sort(ArrayList.java:1462) ~[?:1.8.0_161]
at java.util.Collections.sort(Collections.java:175) ~[?:1.8.0_161]
at java.net.CookieManager.sortByPath(CookieManager.java:412) ~[?:1.8.0_161]
at java.net.CookieManager.get(CookieManager.java:246) ~[?:1.8.0_161]
While we've not been able to suitable data into the CookieManager to reproduce this crash, we have provided a test program that demonstrates the problem
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
I have written a test class that demonstrates that sorting cookies with the CookiePathComparator can cause a crash. It uses a dummy HttpCookie that implements the getName() and getPath() methods as required by the comparator, and I have copied the implementation of CookiePathComparator
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No crash
ACTUAL -
Crash
---------- BEGIN SOURCE ----------
package seo.spider.unit;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class JavaBug
{
public static void main(
final String[] args)
{
// This list in this order causes the crash.
final List<HttpCookieDummy> cookies = Stream.of("charlie/alfa/", "charlie/", "india/echo/", "foxtrot/echo/", "hotel/charlie/", "alfa/", "golf/india/", "golf/", "echo/golf/", "bravo/india/", "golf/alfa/", "echo/alfa/", "bravo/alfa/", "foxtrot/golf/", "golf/golf/", "delta/golf/", "juliett/golf/", "juliett/charlie/", "hotel/echo/", "echo/charlie/", "india/golf/", "delta/echo/", "india/", "india/charlie/", "india/alfa/", "charlie/charlie/", "delta/charlie/", "bravo/charlie/", "echo/india/", "delta/india/", "delta/alfa/", "foxtrot/charlie/", "hotel/alfa/", "foxtrot/alfa/", "charlie/golf/", "echo/echo/", "juliett/india/", "golf/charlie/", "juliett/echo/", "charlie/india/", "bravo/golf/", "echo/", "india/india/", "hotel/india/", "foxtrot/india/", "juliett/alfa/", "hotel/golf/", "bravo/echo/", "golf/echo/", "charlie/echo/")
.map(HttpCookieDummy::new)
.collect(Collectors.toList());
cookies.sort(new HttpCookieDummyComparator());
}
// Dummies enough of the HttpCookie API to demonstrate this bug
private static class HttpCookieDummy
{
private final String mPath;
public HttpCookieDummy(final String path)
{
mPath = path;
}
public String getName()
{
return "name";
}
public String getPath()
{
return mPath;
}
}
// Copied from CookieManager.java
private static class HttpCookieDummyComparator implements Comparator<HttpCookieDummy>
{
public int compare(HttpCookieDummy c1, HttpCookieDummy c2) {
if (c1 == c2) return 0;
if (c1 == null) return -1;
if (c2 == null) return 1;
// path rule only applies to the cookies with same name
if (!c1.getName().equals(c2.getName())) return 0;
// those with more specific Path attributes precede those with less specific
if (c1.getPath().startsWith(c2.getPath()))
return -1;
else if (c2.getPath().startsWith(c1.getPath()))
return 1;
else
return 0;
}
}
}
---------- END SOURCE ----------
FREQUENCY : occasionally
We've seen the crash on Windows 10 and macOS 10.13
A DESCRIPTION OF THE PROBLEM :
We've had this crash multiple times in our application:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:899) ~[?:1.8.0_161]
at java.util.TimSort.mergeAt(TimSort.java:516) ~[?:1.8.0_161]
at java.util.TimSort.mergeForceCollapse(TimSort.java:457) ~[?:1.8.0_161]
at java.util.TimSort.sort(TimSort.java:254) ~[?:1.8.0_161]
at java.util.Arrays.sort(Arrays.java:1512) ~[?:1.8.0_161]
at java.util.ArrayList.sort(ArrayList.java:1462) ~[?:1.8.0_161]
at java.util.Collections.sort(Collections.java:175) ~[?:1.8.0_161]
at java.net.CookieManager.sortByPath(CookieManager.java:412) ~[?:1.8.0_161]
at java.net.CookieManager.get(CookieManager.java:246) ~[?:1.8.0_161]
While we've not been able to suitable data into the CookieManager to reproduce this crash, we have provided a test program that demonstrates the problem
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
I have written a test class that demonstrates that sorting cookies with the CookiePathComparator can cause a crash. It uses a dummy HttpCookie that implements the getName() and getPath() methods as required by the comparator, and I have copied the implementation of CookiePathComparator
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No crash
ACTUAL -
Crash
---------- BEGIN SOURCE ----------
package seo.spider.unit;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class JavaBug
{
public static void main(
final String[] args)
{
// This list in this order causes the crash.
final List<HttpCookieDummy> cookies = Stream.of("charlie/alfa/", "charlie/", "india/echo/", "foxtrot/echo/", "hotel/charlie/", "alfa/", "golf/india/", "golf/", "echo/golf/", "bravo/india/", "golf/alfa/", "echo/alfa/", "bravo/alfa/", "foxtrot/golf/", "golf/golf/", "delta/golf/", "juliett/golf/", "juliett/charlie/", "hotel/echo/", "echo/charlie/", "india/golf/", "delta/echo/", "india/", "india/charlie/", "india/alfa/", "charlie/charlie/", "delta/charlie/", "bravo/charlie/", "echo/india/", "delta/india/", "delta/alfa/", "foxtrot/charlie/", "hotel/alfa/", "foxtrot/alfa/", "charlie/golf/", "echo/echo/", "juliett/india/", "golf/charlie/", "juliett/echo/", "charlie/india/", "bravo/golf/", "echo/", "india/india/", "hotel/india/", "foxtrot/india/", "juliett/alfa/", "hotel/golf/", "bravo/echo/", "golf/echo/", "charlie/echo/")
.map(HttpCookieDummy::new)
.collect(Collectors.toList());
cookies.sort(new HttpCookieDummyComparator());
}
// Dummies enough of the HttpCookie API to demonstrate this bug
private static class HttpCookieDummy
{
private final String mPath;
public HttpCookieDummy(final String path)
{
mPath = path;
}
public String getName()
{
return "name";
}
public String getPath()
{
return mPath;
}
}
// Copied from CookieManager.java
private static class HttpCookieDummyComparator implements Comparator<HttpCookieDummy>
{
public int compare(HttpCookieDummy c1, HttpCookieDummy c2) {
if (c1 == c2) return 0;
if (c1 == null) return -1;
if (c2 == null) return 1;
// path rule only applies to the cookies with same name
if (!c1.getName().equals(c2.getName())) return 0;
// those with more specific Path attributes precede those with less specific
if (c1.getPath().startsWith(c2.getPath()))
return -1;
else if (c2.getPath().startsWith(c1.getPath()))
return 1;
else
return 0;
}
}
}
---------- END SOURCE ----------
FREQUENCY : occasionally
- duplicates
-
JDK-7128479 HttpURLConnection stores the "Set-Cookie" list in a reversed sequence
-
- Closed
-