Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 361121

Summary: [Progress] DetailedProgressViewer's comparator violates its general contract
Product: [Eclipse Project] Platform Reporter: Dani Megert <daniel_megert>
Component: UIAssignee: Paul Webster <pwebster>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: ericdp, javadev, loskutov, nitram509, pwebster, remy.suen, simon.goodall
Version: 3.8   
Target Milestone: 4.2 M5   
Hardware: PC   
OS: Windows 7   
See Also: https://bugs.eclipse.org/bugs/show_bug.cgi?id=525287
https://bugs.eclipse.org/bugs/show_bug.cgi?id=562314
Whiteboard:
Attachments:
Description Flags
JUnit (3.8) test case, proving that JobInfo violates compareTo() method contract
none
JobInfo compareTo test
none
JUnit (3.8) test case, proving that JobInfo violates compareTo() method contract
pwebster: iplog+
JUnit (3.8) test case, checks when jobs sorted by their state, the running ones are ordered to first place
pwebster: iplog+
FIX that correctly compares job states, according to method contract
pwebster: iplog+
Patch that describes all 3 changes none

Description Dani Megert CLA 2011-10-17 07:10:51 EDT
N20111013-2000.

The DetailedProgressViewer's comparator violates its general contract:

!ENTRY org.eclipse.ui 4 4 2011-10-17 13:08:45.365
!MESSAGE An internal error has occurred.
!STACK 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 org.eclipse.jface.viewers.ViewerComparator.sort(ViewerComparator.java:185)
	at org.eclipse.ui.internal.progress.DetailedProgressViewer.add(DetailedProgressViewer.java:166)
	at org.eclipse.ui.internal.progress.ProgressViewerContentProvider.add(ProgressViewerContentProvider.java:224)
	at org.eclipse.ui.internal.progress.ProgressViewUpdater$1.runInUIThread(ProgressViewUpdater.java:285)
	at org.eclipse.ui.progress.UIJob$1.run(UIJob.java:95)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4140)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3757)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
	at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:352)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:624)
Comment 1 Dani Megert CLA 2011-11-23 05:31:08 EST
The bug is in org.eclipse.ui.internal.progress.JobTreeElement.compareTo(Object) or one of its subclasses.
Comment 2 Paul Webster CLA 2011-11-23 08:43:27 EST
My guess would be: org.eclipse.ui.internal.progress.JobInfo with it's convoluted compareTo.

PW
Comment 3 Remy Suen CLA 2011-11-23 09:26:25 EST
(In reply to comment #2)
> My guess would be: org.eclipse.ui.internal.progress.JobInfo with it's
> convoluted compareTo.

Likely. There seems to be a wide variety of issues here. Some or all of which may be contributing to this error.

JobTreeElement:
-implements compareTo(Object) but returns 0 if it's not a JobTreeElement, sounds like a CCE is better?
-no equals(Object) implementation

ErrorInfo:
-reimplements compareTo(Object) but doesn't implement equals(Object)

GroupInfo:
-(unnecessarily) reimplements compareTo(Object) but doesn't implement equals(Object), its code is almost identical to JobTreeElement

JobInfo:
-same as ErrorInfo
-consider the case where the two objects are equal except their states and neither of their states are Job.RUNNING, then _both_ jobInfoA.compareTo(jobInfoB) _and_ jobInfoB.compareTo(jobInfoA) will return 1 (at the end of the method)
Comment 4 Paul Webster CLA 2011-12-12 19:03:25 EST
See bug 364735 comment #44 for an example of our logging when this fails.

PW
Comment 5 Andrey Loskutov CLA 2011-12-13 02:09:28 EST
It was org.eclipse.ui.internal.progress.JobInfo.
P.S. Please consider to backport the fix to 3.7.2 too (current target is 3.8).
Comment 6 Martin W. Kirst CLA 2011-12-13 18:25:13 EST
(In reply to comment #5)
> It was org.eclipse.ui.internal.progress.JobInfo.
> P.S. Please consider to backport the fix to 3.7.2 too (current target is 3.8).

What do you mean by that "... it was ...JobInfo" ?
Is there a patch/commit link available?

Regards
 Martin
Comment 7 Paul Webster CLA 2011-12-14 07:13:25 EST
(In reply to comment #6)
> What do you mean by that "... it was ...JobInfo" ?
> Is there a patch/commit link available?

He means of the possible types that could cause this bug listed in comment #3 JobInfo seems to be the culprit.

This is not the same root cause as the other comparator bug.

PW
Comment 8 Martin W. Kirst CLA 2011-12-14 15:51:31 EST
(In reply to comment #7)
> (In reply to comment #6)
> > What do you mean by that "... it was ...JobInfo" ?
> > Is there a patch/commit link available?
> 
> He means of the possible types that could cause this bug listed in comment #3
> JobInfo seems to be the culprit.
> 
> This is not the same root cause as the other comparator bug.
> 
> PW

Understood.
Looking at JobInfo.java I also would vote for it, being the culprit.

Regards
 Martin
Comment 9 Martin W. Kirst CLA 2011-12-14 17:39:00 EST
Created attachment 208414 [details]
JUnit (3.8) test case, proving that JobInfo violates compareTo() method contract

Iv've created a JUnit Test to prove, that JobInfo violates compareTo() 
method contract (see attachment).

Please, can someone verify?

After verification I would like to continue code a new compareTo() implementation.
Comment 10 Paul Webster CLA 2011-12-15 12:01:57 EST
Created attachment 208452 [details]
JobInfo compareTo test

Hi Martin,

I've turned your file into a patch that applies against master.  I haven't quite looked at it yet, but could you use http://wiki.eclipse.org/Platform_UI/How_to_Contribute and this patch to contribute any more changes you'd like to see us look at.

Thanx for the tests,
PW
Comment 11 Martin W. Kirst CLA 2011-12-15 15:42:59 EST
(In reply to comment #10)
> Created attachment 208452 [details]
> JobInfo compareTo test
> 
> Hi Martin,
> 
> I've turned your file into a patch that applies against master.  I haven't
> quite looked at it yet, but could you use
> http://wiki.eclipse.org/Platform_UI/How_to_Contribute and this patch to
> contribute any more changes you'd like to see us look at.
> 
> Thanx for the tests,
> PW

Thanks.

I'm curious, what you will report, after running the test.

What exactly my patched was missing in contrast to the Wiki how to
(where can I improve) ?
Comment 12 Remy Suen CLA 2011-12-16 00:23:52 EST
(In reply to comment #11)
> What exactly my patched was missing in contrast to the Wiki how to
> (where can I improve) ?

You attached a raw Java file and not a patch (a diff) that can be applied by Eclipse.
Comment 13 Paul Webster CLA 2011-12-16 09:38:41 EST
(In reply to comment #11)
> I'm curious, what you will report, after running the test.

The comment I have on the test itself is that it's just a pass or fail.  Is there no way to break it up to several tests so that fixing a failure can show progress?  if not, don't worry about it, I think the test is good.

> 
> What exactly my patched was missing in contrast to the Wiki how to
> (where can I improve) ?

I appreciate you providing a test ... tests are good :-)

JobInfoTest needed to go in our test plugin, org.eclipse.ui.tests, and required a minor mod to JobInfo to compile.  As Remy mentioned, we take contributions are either patches (the format that needs to be attached to a bug) or pull requests.  I thought I'd just provide the starting point, pointing you to wiki docs is OK but an apply-able patch is better :-)

PW
Comment 14 Martin W. Kirst CLA 2011-12-18 07:34:25 EST
Created attachment 208524 [details]
JUnit (3.8) test case, proving that JobInfo violates compareTo() method contract

Reworked the test to be a patch.
Also added my name and email within contribution section.

So I think, Paul Websters attachment made in Comment #10 should be obsolete.
Comment 15 Martin W. Kirst CLA 2011-12-18 08:27:14 EST
Created attachment 208525 [details]
JUnit (3.8) test case, checks when jobs sorted by their state, the running ones are ordered to first place

Adding one more Test.
This will work fine with current implementation but is an requirement
for upcoming FIX.
Comment 16 Martin W. Kirst CLA 2011-12-18 08:35:41 EST
Created attachment 208526 [details]
FIX that correctly compares job states, according to method contract


Hi,

thanks to the unit test, the root cause was easy to find:
When comparing job states, all states (none, sleeping, waiting, running)
have to be compared by their correlated integer value.
If not (before this FIX), the comparator method contract was violated.

The FIX looks similar to Integer.compareTo() but inverses the ordering,
because we want to have running jobs in pool position.

From my point of view, this bug can be reviewed and closed now ;-)

Regards
 Martin
Comment 17 Paul Webster CLA 2011-12-21 14:03:25 EST
Created attachment 208705 [details]
Patch that describes all 3 changes

This is the combined patch for 3 attachments from Martin.

Martin, if you look at stuff in the future can you use http://wiki.eclipse.org/Platform_UI/How_to_Contribute ?  We're in the transition to git and the patches you gave tend to be CVS patches.  I've made sure they apply clean.

PW
Comment 19 Paul Webster CLA 2012-01-24 13:57:41 EST
The changes are in I20120123-2200
PW
Comment 20 Eric Peters CLA 2012-01-30 09:20:31 EST
Is this bug specific to eclipse running on Java 7? This forum post http://www.eclipse.org/forums/index.php/m/756308/ suggests that JRE 1.7 no longer tolerates this exception as it did previously. I'm interested to get a list of bugs related to eclipse running on Java 7 that exist post eclipse 362.
Comment 21 Dani Megert CLA 2012-01-30 09:34:49 EST
(In reply to comment #20)
> Is this bug specific to eclipse running on Java 7?
Yes.

> I'm interested to get a
> list of bugs related to eclipse running on Java 7 that exist post eclipse 362.

There can be many related to wrongly implemented comparators. The most severe one being bug 317785. Instead of trying to catch all these, you'd better set the following system property in your product:

-Djava.util.Arrays.useLegacyMergeSort=true
Comment 22 Paul Webster CLA 2012-07-19 09:41:28 EDT
*** Bug 385485 has been marked as a duplicate of this bug. ***
Comment 23 Andrey Loskutov CLA 2016-09-08 06:40:57 EDT
*** Bug 403533 has been marked as a duplicate of this bug. ***