eclipse-platform/eclipse.platform

TextMergeView Unhandled IndexOutOfBoundsException

Closed this issue · 16 comments

What steps will reproduce the problem?

  1. open java class into team/ src compare pane
  2. click on src code (even mouse over works)
  3. src compare should highlight code "lines" connecting old and new code. But we get an error.

-- Error Details --
eclipse.buildId=4.33.0.20240829-0648
java.version=22.0.1
java.vendor=Eclipse Adoptium
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=it_IT
Framework arguments: -product org.eclipse.epp.package.java.product
Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.java.product

This is a continuation of log file C:\eclipse_workspace_rel-8_0.metadata.bak_0.log
Created Time: 2024-09-02 09:46:19.979

Exception:
java.lang.IndexOutOfBoundsException: Index 13 out of bounds for length 13
at java.base/jdk.internal.util.Preconditions.outOfBounds(Unknown Source)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Unknown Source)
at java.base/jdk.internal.util.Preconditions.checkIndex(Unknown Source)
at java.base/java.util.Objects.checkIndex(Unknown Source)
at java.base/java.util.ArrayList.get(Unknown Source)
at org.eclipse.compare.contentmergeviewer.TextMergeViewer.getHeightBetweenLines(TextMergeViewer.java:4242)
at org.eclipse.compare.contentmergeviewer.TextMergeViewer.getDiffUnderMouse(TextMergeViewer.java:2310)
at org.eclipse.compare.contentmergeviewer.TextMergeViewer.handleMouseMoveOverCenter(TextMergeViewer.java:2514)
at org.eclipse.compare.contentmergeviewer.TextMergeViewer$HoverResizer.mouseMove(TextMergeViewer.java:2449)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:229)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:91)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4326)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1174)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4124)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3712)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1151)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1042)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153)
at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:639)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:546)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:173)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:208)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:143)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:109)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:439)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:271)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:668)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:605)
at org.eclipse.equinox.launcher.Main.run(Main.java:1481)

Screenshot 2024-05-30 194549

Screenshot 2024-06-28 090800

maybe connected to this ?

Screenshot 2024-09-02 102005

eclipse.buildId=4.33.0.20240829-0648
java.version=22.0.1
java.vendor=Eclipse Adoptium
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=it_IT
Framework arguments: -product org.eclipse.epp.package.java.product
Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.java.product

This is a continuation of log file C:\eclipse_workspace_rel-8_0.metadata.bak_7.log
Created Time: 2024-09-02 10:14:03.344

org.eclipse.ui.workbench
Error
Mon Sep 02 10:14:27 CEST 2024
An internal error has occurred.

org.eclipse.swt.SWTException: Widget is disposed
at org.eclipse.swt.SWT.error(SWT.java:4922)
at org.eclipse.swt.SWT.error(SWT.java:4837)
at org.eclipse.swt.SWT.error(SWT.java:4808)
at org.eclipse.swt.widgets.Widget.error(Widget.java:500)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:419)
at org.eclipse.swt.widgets.Control.getParent(Control.java:1449)
at org.eclipse.compare.contentmergeviewer.TextMergeViewer.updateToolbarLabel(TextMergeViewer.java:5422)
at org.eclipse.compare.contentmergeviewer.TextMergeViewer.update(TextMergeViewer.java:5416)
at org.eclipse.compare.contentmergeviewer.TextMergeViewer$ContributorInfo$1.runInUIThread(TextMergeViewer.java:1102)
at org.eclipse.ui.progress.UIJob.lambda$0(UIJob.java:148)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:132)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4099)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3715)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.block(ModalContext.java:168)
at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:370)
at org.eclipse.jface.dialogs.ProgressMonitorDialog.run(ProgressMonitorDialog.java:470)
at org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog.run(ProgressMonitorJobsDialog.java:230)
at org.eclipse.ui.internal.progress.ProgressManager.lambda$26(ProgressManager.java:819)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:67)
at org.eclipse.ui.internal.progress.ProgressManager.busyCursorWhile(ProgressManager.java:849)
at org.eclipse.ui.internal.progress.ProgressManager.busyCursorWhile(ProgressManager.java:828)
at org.eclipse.ui.internal.progress.ProgressManager.run(ProgressManager.java:977)
at org.eclipse.compare.internal.Utilities.executeRunnable(Utilities.java:898)
at org.eclipse.compare.internal.CompareContainer.run(CompareContainer.java:70)
at org.eclipse.compare.CompareEditorInput.run(CompareEditorInput.java:1317)
at org.eclipse.compare.internal.merge.DocumentMerger.doDiff(DocumentMerger.java:407)
at org.eclipse.compare.contentmergeviewer.TextMergeViewer.doDiff(TextMergeViewer.java:3512)
at org.eclipse.compare.contentmergeviewer.TextMergeViewer$18.runInUIThread(TextMergeViewer.java:3138)
at org.eclipse.ui.progress.UIJob.lambda$0(UIJob.java:148)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:132)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4099)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3715)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1151)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1042)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153)
at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:639)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:546)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:173)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:208)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:143)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:109)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:439)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:271)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:668)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:605)
at org.eclipse.equinox.launcher.Main.run(Main.java:1481)

maybe connected to this ?

@MikOfClassX: Could you please attach entire log file so we don't need to guess?

open java class into team/ src compare pane

@MikOfClassX: Could you please provide exact steps to reproduce that do not rely on your project code. How do you "open src compare pane"?

java.lang.IndexOutOfBoundsException: Index 13 out of bounds for length 13
at java.base/jdk.internal.util.Preconditions.outOfBounds(Unknown Source)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Unknown Source)
at java.base/jdk.internal.util.Preconditions.checkIndex(Unknown Source)
at java.base/java.util.Objects.checkIndex(Unknown Source)
at java.base/java.util.ArrayList.get(Unknown Source)
at org.eclipse.compare.contentmergeviewer.TextMergeViewer.getHeightBetweenLines(TextMergeViewer.java:4242)

This above looks like regression from either #1492 or #1369 or both :-(

org.eclipse.swt.SWTException: Widget is disposed
at org.eclipse.swt.SWT.error(SWT.java:4922)
at org.eclipse.swt.SWT.error(SWT.java:4837)
at org.eclipse.swt.SWT.error(SWT.java:4808)
at org.eclipse.swt.widgets.Widget.error(Widget.java:500)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:419)
at org.eclipse.swt.widgets.Control.getParent(Control.java:1449)
at org.eclipse.compare.contentmergeviewer.TextMergeViewer.updateToolbarLabel(TextMergeViewer.java:5422)

This looks like a regression from #1319.

@DenisUngemach: could you please check?

Looks like the listener in TextMergeViewer.handlePropertyChangeEvent() can clear the lineHeightsByViewer while the diff editor is in use via TextMergeViewer.getHeightBetweenLines(). The code in later should be aware about that.

Hi,

so 1) the IndexOutOfBoundsException happens when double-clicking on a class in the Synchronize pane.

i.e. you select a class and you see the Java Structure Compare, which is ok.
Just below there's the Java Source Compare where you should see a line-by-line compare between your source code and the one in the repository (remote file).
The problem happens when comparing methods, while compilation unit compare is ok.

the other maybe-related issue 2) Widget is disposed happens when updating (i.e. cvs-update) your local source code with the one from the remote file.

I hope this helps. Pls tell me which log file to send and where to retrieve it. Cheers!

Pls tell me which log file to send and where to retrieve it.

Attach it to the ticket here.

got this one from .metadata

e.log

so 1) the IndexOutOfBoundsException happens when double-clicking on a class in the Synchronize pane.

i.e. you select a class and you see the Java Structure Compare, which is ok. Just below there's the Java Source Compare where you should see a line-by-line compare between your source code and the one in the repository (remote file). The problem happens when comparing methods, while compilation unit compare is ok.

So the very first precondition is to open Synchronize view?
And how do you compare methods?

Could you please provide clear & full step by step instructions? May be even a screen cast if possible?

recording.mp4

So the very first precondition is to open Synchronize view? And how do you compare methods?

yes

Could you please provide clear & full step by step instructions? May be even a screen cast if possible?

here we are

recording1.mp4

this is the internal error, on update

I can confirm this following the steps above using 4.33.0.I20240828-1820. The trigger is to double-click on one of the entries in the Compare tree:

  1. Open a Java source file in the compare editor
  2. Double-click on an entry in the compare tree ("Java Structure Compare")
  3. Many exceptions are thrown like this one:
java.lang.IndexOutOfBoundsException: Index 10 out of bounds for length 10
	at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
	at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
	at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266)
	at java.base/java.util.Objects.checkIndex(Objects.java:361)
	at java.base/java.util.ArrayList.get(ArrayList.java:427)
	at org.eclipse.compare.contentmergeviewer.TextMergeViewer.getHeightBetweenLines(TextMergeViewer.java:4242)
	at org.eclipse.compare.contentmergeviewer.TextMergeViewer.getDiffUnderMouse(TextMergeViewer.java:2310)
	at org.eclipse.compare.contentmergeviewer.TextMergeViewer.handleMouseMoveOverCenter(TextMergeViewer.java:2514)
	at org.eclipse.compare.contentmergeviewer.TextMergeViewer$HoverResizer.mouseMove(TextMergeViewer.java:2449)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:229)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:91)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4660)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1622)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1645)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1630)
	at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1392)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4427)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4003)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1151)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1042)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153)
	at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:639)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:546)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:173)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:208)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:143)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:109)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:439)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:271)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:668)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:605)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1481)

If I do the same thing in 4.32.0.I20240601-0610 I get:

java.lang.IllegalArgumentException: Argument not valid
	at org.eclipse.swt.SWT.error(SWT.java:4903)
	at org.eclipse.swt.SWT.error(SWT.java:4837)
	at org.eclipse.swt.SWT.error(SWT.java:4808)
	at org.eclipse.swt.custom.StyledText.getLineVerticalIndent(StyledText.java:3788)
	at org.eclipse.compare.contentmergeviewer.TextMergeViewer.getHeightBetweenLines(TextMergeViewer.java:4211)
	at org.eclipse.compare.contentmergeviewer.TextMergeViewer.paintSides(TextMergeViewer.java:4441)
	at org.eclipse.compare.contentmergeviewer.TextMergeViewer.lambda$4(TextMergeViewer.java:2147)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:247)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:91)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4660)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1622)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1645)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1630)
	at org.eclipse.swt.widgets.Control.drawWidget(Control.java:1237)
	at org.eclipse.swt.widgets.Canvas.drawWidget(Canvas.java:176)
	at org.eclipse.swt.widgets.Widget.drawRect(Widget.java:819)
	at org.eclipse.swt.widgets.Canvas.drawRect(Canvas.java:170)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:6254)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
	at org.eclipse.swt.widgets.Display.applicationNextEventMatchingMask(Display.java:5578)
	at org.eclipse.swt.widgets.Display.applicationProc(Display.java:5979)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSend(Native Method)
	at org.eclipse.swt.internal.cocoa.NSApplication.nextEventMatchingMask(NSApplication.java:92)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3997)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1151)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1042)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:152)
	at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:639)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:546)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:173)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:208)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:143)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:109)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:439)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:271)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:668)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:605)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1481)

This is perfectly working on Version: 2024-09 M1 (4.33.0 M1) Build id: 20240618-0159.
A regression, maybe ?

I will check this.
Thanks for reporting.

It seems the method getHeightBetweenLines can be called with values which are higher than the number of lines in the StyledText.
This is unexpected.
In this case it might be necessary to improvise.

This PR should fix the problem properly.
I also added a fallback handling in order to prevent a runtime exception, although now the method will be called in the right way. But i guess not exact drawings are still better than runtime exceptions.

@MikOfClassX: Thank's for reporting. This is fixed in the next nightly-build (i-build) and in the next milestone and release.