Bug 332843 - [formatter] format save action fails with SIOOBE
Summary: [formatter] format save action fails with SIOOBE
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.7   Edit
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: 3.7 M5   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 333552 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-12-17 08:05 EST by Benno Baumgartner CLA
Modified: 2011-01-25 08:41 EST (History)
3 users (show)

See Also:


Attachments
My Formatter Settings (29.51 KB, text/xml)
2010-12-17 08:05 EST, Benno Baumgartner CLA
no flags Details
Proposed fix (900 bytes, patch)
2010-12-17 11:23 EST, Olivier Thomann CLA
no flags Details | Diff
Proposed fix (1.28 KB, patch)
2010-12-17 11:29 EST, Olivier Thomann CLA
no flags Details | Diff
ZIP with test project (15.16 KB, application/x-java-archive)
2011-01-06 07:10 EST, Dani Megert CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Benno Baumgartner CLA 2010-12-17 08:05:07 EST
Created attachment 185417 [details]
My Formatter Settings

I20101208-1300

Starting with 3.7M4 I get the following exception quite often (and a dialog) on save. I have format edited lines on save enabled. See attached formatter settings. Sorry, no exact steps to reproduce yet.

!ENTRY org.eclipse.jdt.ui 4 10006 2010-12-17 13:59:42.160
!MESSAGE The save participant 'org.eclipse.jdt.ui.postsavelistener.cleanup' caused an exception: java.lang.StringIndexOu
tOfBoundsException: String index out of range: 0
!STACK 0
java.lang.StringIndexOutOfBoundsException: String index out of range: 0
        at java.lang.String.charAt(Unknown Source)
        at org.eclipse.jdt.internal.formatter.Scribe.adaptEdit(Scribe.java:455)
        at org.eclipse.jdt.internal.formatter.Scribe.adaptEdits(Scribe.java:284)
        at org.eclipse.jdt.internal.formatter.Scribe.getRootEdit(Scribe.java:1244)
        at org.eclipse.jdt.internal.formatter.CodeFormatterVisitor.format(CodeFormatterVisitor.java:818)
        at org.eclipse.jdt.internal.formatter.DefaultCodeFormatter.formatCompilationUnit(DefaultCodeFormatter.java:241)
        at org.eclipse.jdt.internal.formatter.DefaultCodeFormatter.format(DefaultCodeFormatter.java:163)
        at org.eclipse.jdt.internal.corext.util.CodeFormatterUtil.reformat(CodeFormatterUtil.java:323)
        at org.eclipse.jdt.internal.corext.fix.CodeFormatFix.createCleanUp(CodeFormatFix.java:74)
        at org.eclipse.jdt.internal.ui.fix.CodeFormatCleanUp.createFix(CodeFormatCleanUp.java:65)
        at org.eclipse.jdt.internal.corext.fix.CleanUpRefactoring.calculateChange(CleanUpRefactoring.java:792)
        at org.eclipse.jdt.internal.corext.fix.CleanUpPostSaveListener.saved(CleanUpPostSaveListener.java:392)
        at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider$5.run(CompilationUnitDocumentProvider.
java:1571)
        at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
        at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider.notifyPostSaveListeners(CompilationUni
tDocumentProvider.java:1566)
        at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider.commitWorkingCopy(CompilationUnitDocum
entProvider.java:1363)
        at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider$4.execute(CompilationUnitDocumentProvi
der.java:1432)
        at org.eclipse.ui.editors.text.TextFileDocumentProvider$DocumentProviderOperation.run(TextFileDocumentProvider.j
ava:132)
        at org.eclipse.ui.actions.WorkspaceModifyDelegatingOperation.execute(WorkspaceModifyDelegatingOperation.java:69)

        at org.eclipse.ui.actions.WorkspaceModifyOperation$1.run(WorkspaceModifyOperation.java:106)
        at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2313)
        at org.eclipse.ui.actions.WorkspaceModifyOperation.run(WorkspaceModifyOperation.java:118)
        at org.eclipse.ui.internal.editors.text.WorkspaceOperationRunner.run(WorkspaceOperationRunner.java:75)
        at org.eclipse.ui.internal.editors.text.WorkspaceOperationRunner.run(WorkspaceOperationRunner.java:65)
        at org.eclipse.ui.editors.text.TextFileDocumentProvider.executeOperation(TextFileDocumentProvider.java:456)
        at org.eclipse.ui.editors.text.TextFileDocumentProvider.saveDocument(TextFileDocumentProvider.java:772)
        at org.eclipse.ui.texteditor.AbstractTextEditor.performSave(AbstractTextEditor.java:5047)
        at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor.performSave(CompilationUnitEditor.java:1230)
        at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor.doSave(CompilationUnitEditor.java:1283)
        at org.eclipse.ui.texteditor.AbstractTextEditor$TextEditorSavable.doSave(AbstractTextEditor.java:7176)
        at org.eclipse.ui.Saveable.doSave(Saveable.java:214)
        at org.eclipse.ui.internal.SaveableHelper.doSaveModel(SaveableHelper.java:349)
        at org.eclipse.ui.internal.SaveableHelper$3.run(SaveableHelper.java:195)
        at org.eclipse.ui.internal.SaveableHelper$5.run(SaveableHelper.java:277)
        at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
        at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:372)
        at org.eclipse.jface.window.ApplicationWindow$1.run(ApplicationWindow.java:759)
        at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
        at org.eclipse.jface.window.ApplicationWindow.run(ApplicationWindow.java:756)
        at org.eclipse.ui.internal.WorkbenchWindow.run(WorkbenchWindow.java:2613)
        at org.eclipse.ui.internal.SaveableHelper.runProgressMonitorOperation(SaveableHelper.java:285)
        at org.eclipse.ui.internal.SaveableHelper.runProgressMonitorOperation(SaveableHelper.java:264)
        at org.eclipse.ui.internal.SaveableHelper.saveModels(SaveableHelper.java:207)
        at org.eclipse.ui.internal.SaveableHelper.savePart(SaveableHelper.java:144)
        at org.eclipse.ui.internal.EditorManager.savePart(EditorManager.java:1369)
        at org.eclipse.ui.internal.WorkbenchPage.savePart(WorkbenchPage.java:3334)
        at org.eclipse.ui.internal.WorkbenchPage.saveEditor(WorkbenchPage.java:3347)
        at org.eclipse.ui.internal.SaveAction.run(SaveAction.java:76)
        at org.eclipse.jface.action.Action.runWithEvent(Action.java:498)
        at org.eclipse.ui.commands.ActionHandler.execute(ActionHandler.java:185)
        at org.eclipse.ui.internal.handlers.LegacyHandlerWrapper.execute(LegacyHandlerWrapper.java:109)
        at org.eclipse.core.commands.Command.executeWithChecks(Command.java:476)
        at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508)
        at org.eclipse.ui.internal.handlers.HandlerService.executeCommand(HandlerService.java:169)
        at org.eclipse.ui.internal.keys.WorkbenchKeyboard.executeCommand(WorkbenchKeyboard.java:468)
        at org.eclipse.ui.internal.keys.WorkbenchKeyboard.press(WorkbenchKeyboard.java:786)
        at org.eclipse.ui.internal.keys.WorkbenchKeyboard.processKeyEvent(WorkbenchKeyboard.java:885)
        at org.eclipse.ui.internal.keys.WorkbenchKeyboard.filterKeySequenceBindings(WorkbenchKeyboard.java:567)
        at org.eclipse.ui.internal.keys.WorkbenchKeyboard.access$3(WorkbenchKeyboard.java:508)
        at org.eclipse.ui.internal.keys.WorkbenchKeyboard$KeyDownFilter.handleEvent(WorkbenchKeyboard.java:123)
        at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
        at org.eclipse.swt.widgets.Display.filterEvent(Display.java:1254)
        at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1052)
        at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1077)
        at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1062)
        at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1103)
        at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1099)
        at org.eclipse.swt.widgets.Widget.wmChar(Widget.java:1508)
        at org.eclipse.swt.widgets.Control.WM_CHAR(Control.java:4273)
        at org.eclipse.swt.widgets.Canvas.WM_CHAR(Canvas.java:345)
        at org.eclipse.swt.widgets.Control.windowProc(Control.java:4165)
        at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:341)
        at org.eclipse.swt.widgets.Display.windowProc(Display.java:4891)
        at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method)
        at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:2465)
        at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3673)
        at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2640)
        at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
        at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438)
        at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671)
        at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
        at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664)
        at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
        at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115)
        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:369)
        at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
        at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
        at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
Comment 1 Olivier Thomann CLA 2010-12-17 11:23:03 EST
Frédéric, please check the patch I am attaching.
Comment 2 Olivier Thomann CLA 2010-12-17 11:23:20 EST
Created attachment 185436 [details]
Proposed fix
Comment 3 Olivier Thomann CLA 2010-12-17 11:29:58 EST
Created attachment 185438 [details]
Proposed fix

This should work better.
Comment 4 Olivier Thomann CLA 2010-12-17 11:31:01 EST
Setting as major as this is causing the formatter to fail.
Comment 5 Frederic Fusier CLA 2010-12-17 11:47:42 EST
(In reply to comment #3)
> Created an attachment (id=185438) [details]
> Proposed fix
> 
> This should work better.

Agreed, that looks good :-S...

Benno, a test case to reproduce this issue would help us to add a
non-regression test :-)
Comment 6 Olivier Thomann CLA 2010-12-17 12:08:48 EST
I am not sure we should release this patch as long as we don't have a regression test.
I put a breakpoint in this code running all the formatter tests and I only hit the breakpoint once with a replacement string length of 2.
So clearly we miss test cases that are using that code intensively.
Comment 7 Olivier Thomann CLA 2011-01-05 08:27:51 EST
*** Bug 333552 has been marked as a duplicate of this bug. ***
Comment 8 Olivier Thomann CLA 2011-01-05 14:33:34 EST
Released for 3.7M5.
A regression test is still needed for this issue.
Comment 9 Benno Baumgartner CLA 2011-01-06 03:07:39 EST
(In reply to comment #8)
> Released for 3.7M5.
> A regression test is still needed for this issue.

Sorry, it's hard to find steps, because after the exception is thrown undo is broken for me, hence I can not go back to the state before the exception was thrown and reproduce the problem.
Comment 10 Dani Megert CLA 2011-01-06 07:09:52 EST
I found reproducible steps from which you can hopefully extract a test case.  I also verified that the fix works.

Steps:
1. start new workspace
2. import the attached ZIP as 'Existing Projects into Workspace'
3. Enable Java > Editor > Save Actions
   - enable Format source code
     - choose Format edited lines
4. open type 'RecipeDocumentProvider'
5. expand the collapsed imports
6. on the third import (line 15) type "xxx" after "org.eclipse"
7. save
==> bug
Comment 11 Dani Megert CLA 2011-01-06 07:10:43 EST
Created attachment 186158 [details]
ZIP with test project
Comment 12 Ayushman Jain CLA 2011-01-25 08:41:15 EST
Verified for 3.7M5 using build I20110124-1800.

Opened bug 335309 to follow up on adding a regression test