osate / osate2

Open Source AADL2 Tool Environment
http://osate.org
Eclipse Public License 2.0
36 stars 8 forks source link

AADL formatter exception when formatting annex without an EMF write transaction #2349

Closed philip-alldredge closed 3 years ago

philip-alldredge commented 4 years ago

Summary

An exception is thrown when saving an xtext resource which contains an AADL annex due to the lack of a write transaction. The AADL formatter re-parses the annex and updates the parsed annex which causes an exception.

In practice, this can occur when using the graphical editor if the xtext editor is not open. The graphical editor may run the formatter when getting the AADL text before and after a modification. All of the graphical editor's modifications are performed in an EMF transaction. I don't think the graphical editor should need to perform all saves in a write transaction.

Expected and Current Behavior

When formatting/saving a model with an annex in it, no exception should be thrown. An exception is thrown because the formatter is modifying the model so update the parsed annex library/subclause contained in the model as part of the formatting operation.

Steps to Reproduce

  1. Attempt to create an Annex library/subclause in the graphical editor without the xtext document being open.
  2. Exception is thrown due to lack of a write transaction.

Environment

!SESSION 2020-06-02 09:39:46.134 ----------------------------------------------- eclipse.buildId=unknown java.version=1.8.0_221 java.vendor=Oracle Corporation BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=en_US Framework arguments: -product org.osate.branding.org.osate.product Command-line arguments: -product org.osate.branding.org.osate.product -data C:\Users\pwa0001\projects\osate\eclipse\osate2_2020-03-master\ws/../runtime-osate2 -dev file:C:/Users/pwa0001/projects/osate/eclipse/osate2_2020-03-master/ws/.metadata/.plugins/org.eclipse.pde.core/OSATE2/dev.properties -os win32 -ws win32 -arch x86_64 -consoleLog

!ENTRY org.osate.ge 4 0 2020-06-02 09:39:47.376 !MESSAGE bundle org.osate.ge:1.2.0.qualifier (1263)Component descriptor entry 'components/DefaultNamingService.xml' not found

!ENTRY org.eclipse.egit.ui 2 0 2020-06-02 09:39:55.932 !MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git user global configuration and to define the default location to store repositories: 'C:\Users\pwa0001'. If this is not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and EGit might behave differently since they see different configuration options. This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. 0 [main] ERROR org.eclipse.xtext.util.ExceptionAcceptor - Cannot modify resource set without a write transaction java.lang.IllegalStateException: Cannot modify resource set without a write transaction at org.eclipse.emf.transaction.impl.TransactionChangeRecorder.assertWriting(TransactionChangeRecorder.java:349) at org.eclipse.emf.transaction.impl.TransactionChangeRecorder.appendNotification(TransactionChangeRecorder.java:303) at org.eclipse.emf.transaction.impl.TransactionChangeRecorder.processObjectNotification(TransactionChangeRecorder.java:285) at org.eclipse.emf.transaction.impl.TransactionChangeRecorder.notifyChanged(TransactionChangeRecorder.java:241) at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:424) at org.eclipse.emf.common.notify.impl.NotificationImpl.dispatch(NotificationImpl.java:1027) at org.osate.aadl2.impl.DefaultAnnexSubclauseImpl.setParsedAnnexSubclause(DefaultAnnexSubclauseImpl.java:172) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter.lambda$506(Aadl2Formatter.java:3222) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter.unsafeFormatAnnexText(Aadl2Formatter.java:5237) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter.formatAnnexText(Aadl2Formatter.java:5218) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter._format(Aadl2Formatter.java:3230) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter.format(Aadl2Formatter.java:5559) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter.lambda$600(Aadl2Formatter.java:4125) at java.lang.Iterable.forEach(Iterable.java:75) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter.formatComponentImplementationCommon(Aadl2Formatter.java:4127) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter._format(Aadl2Formatter.java:4192) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter.format(Aadl2Formatter.java:5412) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter.lambda$197(Aadl2Formatter.java:1348) at java.lang.Iterable.forEach(Iterable.java:75) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter.formatPackageSectionCommon(Aadl2Formatter.java:1350) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter._format(Aadl2Formatter.java:1251) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter.format(Aadl2Formatter.java:5592) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter._format(Aadl2Formatter.java:1153) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter.format(Aadl2Formatter.java:5607) at org.eclipse.xtext.formatting2.internal.FormattableDocument.format(FormattableDocument.java:188) at org.eclipse.xtext.formatting2.AbstractFormatter2._format(AbstractFormatter2.java:208) at org.osate.xtext.aadl2.formatting2.Aadl2Formatter.format(Aadl2Formatter.java:5685) at org.eclipse.xtext.formatting2.AbstractFormatter2.format(AbstractFormatter2.java:276) at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:151) at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:198) at org.eclipse.xtext.resource.XtextResource.doSave(XtextResource.java:386) at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1475) at org.osate.ge.internal.services.impl.DefaultAadlModificationService.getText(DefaultAadlModificationService.java:428) at org.osate.ge.internal.services.impl.DefaultAadlModificationService.performModification(DefaultAadlModificationService.java:309) at org.osate.ge.internal.services.impl.DefaultAadlModificationService.access$4(DefaultAadlModificationService.java:275) at org.osate.ge.internal.services.impl.DefaultAadlModificationService$1ModificationAction.execute(DefaultAadlModificationService.java:153) at org.osate.ge.internal.services.impl.DefaultActionService.execute(DefaultActionService.java:305) at org.osate.ge.internal.services.impl.DefaultAadlModificationService.performModifications(DefaultAadlModificationService.java:178) at org.osate.ge.internal.services.impl.DefaultAadlModificationService.lambda$0(DefaultAadlModificationService.java:115) at org.osate.ge.internal.services.impl.DefaultAadlModificationService.runInDisplayThread(DefaultAadlModificationService.java:121) at org.osate.ge.internal.services.impl.DefaultAadlModificationService.modify(DefaultAadlModificationService.java:115) at org.osate.ge.internal.operations.OperationExecutor.execute(OperationExecutor.java:77) at org.osate.ge.internal.graphiti.features.BoHandlerCreateFeature$1CreateAction.execute(BoHandlerCreateFeature.java:177) at org.osate.ge.internal.services.impl.DefaultActionService.execute(DefaultActionService.java:305) at org.osate.ge.internal.services.impl.DefaultActionService.execute(DefaultActionService.java:299) at org.osate.ge.internal.ui.editor.AgeDiagramBehavior.lambda$13(AgeDiagramBehavior.java:1211) at org.osate.ge.internal.graphiti.services.impl.DefaultGraphitiService.execute(DefaultGraphitiService.java:93) at org.osate.ge.internal.graphiti.features.BoHandlerCreateFeature.create(BoHandlerCreateFeature.java:191) at org.eclipse.graphiti.features.impl.AbstractCreateFeature.execute(AbstractCreateFeature.java:94) at org.eclipse.graphiti.internal.command.GenericFeatureCommandWithContext.execute(GenericFeatureCommandWithContext.java:58) at org.eclipse.graphiti.internal.command.GFPreparableCommand.doExecute(GFPreparableCommand.java:34) at org.eclipse.emf.transaction.RecordingCommand.execute(RecordingCommand.java:135) at org.eclipse.graphiti.ui.internal.editor.GFWorkspaceCommandStackImpl.execute(GFWorkspaceCommandStackImpl.java:125) at org.eclipse.emf.transaction.impl.AbstractTransactionalCommandStack.execute(AbstractTransactionalCommandStack.java:219) at org.eclipse.graphiti.internal.command.CommandExec.executeCommand(CommandExec.java:82) at org.eclipse.graphiti.ui.internal.command.CreateModelObjectCommand.execute(CreateModelObjectCommand.java:46) at org.eclipse.graphiti.ui.internal.editor.EmfOnGefCommand.execute(EmfOnGefCommand.java:51) at org.eclipse.graphiti.internal.command.GFPreparableCommand2.doExecute(GFPreparableCommand2.java:40) at org.eclipse.emf.transaction.RecordingCommand.execute(RecordingCommand.java:135) at org.eclipse.emf.workspace.EMFCommandOperation.doExecute(EMFCommandOperation.java:119) at org.eclipse.emf.workspace.AbstractEMFOperation.execute(AbstractEMFOperation.java:150) at org.eclipse.core.commands.operations.DefaultOperationHistory.execute(DefaultOperationHistory.java:496) at org.eclipse.emf.workspace.impl.WorkspaceCommandStackImpl.doExecute(WorkspaceCommandStackImpl.java:208) at org.eclipse.emf.transaction.impl.AbstractTransactionalCommandStack.execute(AbstractTransactionalCommandStack.java:165) at org.eclipse.graphiti.ui.internal.editor.GFWorkspaceCommandStackImpl.execute(GFWorkspaceCommandStackImpl.java:94) at org.eclipse.graphiti.ui.internal.editor.GFCommandStack.execute(GFCommandStack.java:136) at org.osate.ge.internal.ui.editor.AgeDiagramBehavior$AgeGFCommandStack.execute(AgeDiagramBehavior.java:250) at org.eclipse.gef.tools.AbstractTool.executeCommand(AbstractTool.java:425) at org.eclipse.gef.tools.AbstractTool.executeCurrentCommand(AbstractTool.java:438) at org.eclipse.gef.tools.CreationTool.performCreation(CreationTool.java:269) at org.eclipse.gef.tools.CreationTool.handleButtonUp(CreationTool.java:189) at org.eclipse.gef.tools.AbstractTool.mouseUp(AbstractTool.java:1200) at org.eclipse.gef.EditDomain.mouseUp(EditDomain.java:301) at org.eclipse.gef.ui.parts.DomainEventDispatcher.dispatchMouseReleased(DomainEventDispatcher.java:380) at org.eclipse.draw2d.LightweightSystem$EventHandler.mouseUp(LightweightSystem.java:548) at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:224) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89) at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4105) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1037) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3922) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3524) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1160) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1049) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155) at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:658) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:557) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:154) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:150) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:137) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:107) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:401) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:657) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:594) at org.eclipse.equinox.launcher.Main.run(Main.java:1447) at org.eclipse.equinox.launcher.Main.main(Main.java:1420)

philip-alldredge commented 4 years ago

@lwrage from my perspective this is a core issue rather than a graphical editor issue even though it likely primarily affects the graphical editor.

lwrage commented 4 years ago

I think we can delete the requirement for a write transaction. IIRC, it's a leftover from before using Xtext.

philip-alldredge commented 4 years ago

That would be very helpful. This used to work but something changed that caused this to start becoming an issue. We'll have annex related tests in the graphical editor in the near future which should catch any regressions.

philip-alldredge commented 4 years ago

Is this something that could be fixed by the next release? As it is, it can cause issues by just having and annex subclause or library in a model.

philip-alldredge commented 4 years ago

@lwrage I was able to confirm that this does not occur in the current stable version of OSATE.

lwrage commented 4 years ago

This is not related to the transactional editing domain used in core OSATE so the above comment about removing the transaction requirement is invalid.

The root cause for this issue is the need for re-parsing the EMV2 annex to format it. This can be avoided only by creating a new AnnexParser interface for use by annexes that are based on Xtext. The current interface must be kept because the BA implementation is not Xtext based.

philip-alldredge commented 4 years ago

You are likely already aware of this, but this issue occurs regardless of whether the annex is even has a parser. Since the parsedAnnexSubclause/Library is set, the transaction error occurs.