eclipse-pde / eclipse.pde

Eclipse Public License 2.0
25 stars 63 forks source link

PDE DS generation causes SWT thread error #431

Open Bananeweizen opened 1 year ago

Bananeweizen commented 1 year ago

Happens when a diff editor is open on the manifest.mf that gets updated by PDE DS. I'm not sure who is the best responsible in the stack trace to wrap an action into a UI thread runnable or similar. I would tend to PDEModelUtilility.generateModelEdits(). Anyone with opinions?

org.eclipse.swt.SWTException: Invalid thread access
    at org.eclipse.swt.SWT.error(SWT.java:4918)
    at org.eclipse.swt.SWT.error(SWT.java:4833)
    at org.eclipse.swt.SWT.error(SWT.java:4804)
    at org.eclipse.swt.widgets.Widget.error(Widget.java:450)
    at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:370)
    at org.eclipse.swt.custom.StyledText.getLinePixel(StyledText.java:3871)
    at org.eclipse.swt.custom.StyledText.handleTextChanging(StyledText.java:6116)
    at org.eclipse.swt.custom.StyledText$5.textChanging(StyledText.java:5402)
    at org.eclipse.jface.text.DefaultDocumentAdapter.fireTextChanging(DefaultDocumentAdapter.java:360)
    at org.eclipse.jface.text.DefaultDocumentAdapter.documentAboutToBeChanged(DefaultDocumentAdapter.java:277)
    at org.eclipse.jface.text.AbstractDocument.fireDocumentAboutToBeChanged(AbstractDocument.java:637)
    at org.eclipse.jface.text.AbstractDocument.replace(AbstractDocument.java:1091)
    at org.eclipse.core.internal.filebuffers.SynchronizableDocument.replace(SynchronizableDocument.java:176)
    at org.eclipse.jface.text.AbstractDocument.replace(AbstractDocument.java:1118)
    at org.eclipse.core.internal.filebuffers.SynchronizableDocument.replace(SynchronizableDocument.java:164)
    at org.eclipse.text.edits.InsertEdit.performDocumentUpdating(InsertEdit.java:78)
    at org.eclipse.text.edits.TextEdit.traverseDocumentUpdating(TextEdit.java:920)
    at org.eclipse.text.edits.TextEdit.traverseDocumentUpdating(TextEdit.java:913)
    at org.eclipse.text.edits.TextEditProcessor.executeDo(TextEditProcessor.java:196)
    at org.eclipse.text.edits.TextEdit.dispatchPerformEdits(TextEdit.java:742)
    at org.eclipse.text.edits.TextEditProcessor.performEdits(TextEditProcessor.java:158)
    at org.eclipse.text.edits.TextEdit.apply(TextEdit.java:714)
    at org.eclipse.text.edits.TextEdit.apply(TextEdit.java:738)
    at org.eclipse.pde.internal.ui.util.PDEModelUtility.generateModelEdits(PDEModelUtility.java:342)
    at org.eclipse.pde.internal.ui.util.PDEModelUtility.modifyModel(PDEModelUtility.java:279)
    at org.eclipse.pde.ds.internal.annotations.DSAnnotationCompilationParticipant.updateProject(DSAnnotationCompilationParticipant.java:445)
    at org.eclipse.pde.ds.internal.annotations.DSAnnotationCompilationParticipant.buildFinished(DSAnnotationCompilationParticipant.java:399)
    at org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:251)
    at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:1020)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:247)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:303)
    at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:392)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:395)
    at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:506)
    at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:454)
    at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:536)
    at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:161)
    at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:255)
    at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
laeubi commented 1 year ago

I think the best place would be at that point where an API first states that it must execute in the SWT Thread.

The one can use Display.execute(...) to make sure the call is always performed in the UI thread.

iloveeclipse commented 1 year ago

I would tend to PDEModelUtilility.generateModelEdits(). Anyone with opinions?

May be one call before, PDEModelUtility.modifyModel() should already check in which thread it runs and in case it is a background one, run the code in UI job.

iloveeclipse commented 1 year ago

I think the best place would be at that point where an API first states that it must execute in the SWT Thread.

That is where PDEModelUtility.modifyModel() does things like

PDEFormEditor editor = getOpenEditor(modification);
IBaseModel model = getModelFromEditor(editor, modification);