Community
Participate
Working Groups
Created attachment 257261 [details] error log with 20 concurrent sessions I'm running load tests against the E4 demo from the e4 incubator with RAP 3.1 M2. I use the e4 bundles from the incubator, all required bundles are taken from the RAP 3.1 / Neon M2 platform. When accessing the demo from a single user session, everything works fine. With concurrent user sessions, different errors end up in the log. The errors seem to be concurrency-related, for example, when running with 20 concurrent sessions, I got only 3 exceptions, with 500 concurrent sessions, there were more than 300. I can observe two types of errors: 1. org.eclipse.e4.core.di.InjectionException: java.lang.IllegalAccessException: Class org.eclipse.e4.core.internal.di.MethodRequestor can not access a member of class org.eclipse.e4.ui.workbench.addons.minmax.MinMaxAddon with modifiers "private" Instead of `MinMaxAddon` this exception also appears with other classes. 2. java.lang.RuntimeException: Cycle while computing valueorg.eclipse.e4.ui.internal.services.ActiveContextsFunction@3d5284c3 This exception also comes with various parameters. I attach two error log files with complete stacktraces, one with 20 concurrent sessions and one with 500 sessions.
Created attachment 257262 [details] error log with 500 concurrent sessions
Both are concurrency issues related to missing synchronization in the requestor implementations in the e4.core.di bundle. These classes access fields or methods using reflection. To be able to access even unaccessible fields and methods, they set accessibility to true before and restore the original accessibility after the operation. This code is not thread-safe. I've pushed a fix to Gerrit: https://git.eclipse.org/r/#/c/62610/
Thanks for identifying these Ralf. I suspect there are some other concurrency issues in the DI that we're just not seeing as most DI use occurs on the UI thread. I think we need to make these accessible checks be controlled by a countup/countdown. I wonder: what are the implications of marking the constructor/field/method as accessible on the Requestor's creation and restoring the accessible flag on dispose()?
Thanks Alwis for looking into it, I agree that reference counting is a better approach. Regarding your second suggestion to keep the thing accessible over the lifetime of the Requestor, that sounds reasonable to me, however, that's a bit outside my field of experience. I'd think the only effect of restoring the original accessibility state is to let getAccessible return the right value to other users of the reflection APIs. But since getAccessible will return the wrong value at some point anyway, question is if there's any good reason to restore it at all... I can update my patch, but will wait for a decision which route to take.
Mass move to M6
Gerrit change https://git.eclipse.org/r/62610 was merged to [master]. Commit: http://git.eclipse.org/c/platform/eclipse.platform.runtime.git/commit/?id=abc59146cff6a0d1d181ad659390543d6c996f8d
Copying in some detail on the AccessibleObject lifecycle that Ralf dug up and attached to the review: > > I think unless we have docs stating that it, for safety we should assume there is one true instance. > > The doc for setAccessible() states that it sets the accessible flag "for *this object*", not for the reflected object. > > This developer works article on reflection [1] says that the setAccessible method "lets you turn the access checks on or off for an *instance* of one of these classes" (i.e. Constructor, Field, and Method). > > > Otherwise why would anybody bother with restoring the accessible flag? > > Interestingly, I couldn't find any reference that recommends restoring the accessibility state. Maybe it was just a misconception. > > Moreover, the fact that you could write a set of unit tests that show the actual effect of setAccessible, and the central role of this method in the reflection API, makes me think that any change in this regard would be a breaking change. Hence I'd tend to consider the actual behavior as a contract. > > [1] http://www.ibm.com/developerworks/library/j-dyn0603/#N101FA
New Gerrit change created: https://git.eclipse.org/r/65122
Gerrit change https://git.eclipse.org/r/65122 was merged to [master]. Commit: http://git.eclipse.org/c/platform/eclipse.platform.runtime.git/commit/?id=d5fe3d0e5e1fe906503533fcef128a0f14374f42
I reverted the fix. Moving the setAccessible() restoration to the IRequestor#disposed() methods isn't sufficient: since the InjectorImpl caches and shares the Field/Method/Constructor instances, and disposed() is called when a context is disposed, we still have the same possible race condition (just a bit less often). Plus I discovered that ConstructorRequestors aren't #disposed(), so we wouldn't be restoring the accessible flag on constructors. Since all uses of the reflection APIs disable the accessible state checks anyways, and adding bookkeeping to InjectorImpl is a bit risky for M5, I'll go ahead with Ralf's patch to remove the restoring of the accessible state. The Injector should be caching the information to inject a class instance as a factory rather than re-processing the same class each time, and any state setting and restoring could be done there.
Haven't seen the message yet, but Ralf's fix is committed as: https://git.eclipse.org/c/platform/eclipse.platform.runtime.git/commit/?id=995c3f8bbc420800fd2fd0535ee2b93f7c65a47d
Today I repeated the load tests with 200 concurrent sessions and Neon M5 platform bundles. The first type of error is gone. Unfortunately, the second error is still reproducible. Here are some stack traces: !ENTRY org.eclipse.e4.ui.workbench 4 0 2016-02-16 10:09:04.406 !MESSAGE Internal Error !STACK 0 java.lang.RuntimeException: Cycle while computing valueorg.eclipse.e4.ui.internal.workbench.ActivePartLookupFunction@e76f47b at org.eclipse.e4.core.internal.contexts.ValueComputation.get(ValueComputation.java:57) at org.eclipse.e4.core.internal.contexts.EclipseContext.internalGet(EclipseContext.java:226) at org.eclipse.e4.core.internal.contexts.EclipseContext.get(EclipseContext.java:213) at org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRenderer$3.changed(ToolBarManagerRenderer.java:358) at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:114) at org.eclipse.e4.core.internal.contexts.EclipseContext.processScheduled(EclipseContext.java:341) at org.eclipse.e4.core.internal.contexts.EclipseContext.set(EclipseContext.java:356) at org.eclipse.e4.core.internal.contexts.EclipseContext.activate(EclipseContext.java:666) at org.eclipse.e4.core.internal.contexts.EclipseContext.activateBranch(EclipseContext.java:672) at org.eclipse.e4.ui.internal.workbench.PartActivationHistory.activate(PartActivationHistory.java:52) at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:704) at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:639) at org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer.activate(AbstractPartRenderer.java:106) at org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer$9.widgetSelected(StackRenderer.java:1104) at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:263) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:109) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:687) at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:594) at org.eclipse.swt.widgets.Display.executeNextEvent(Display.java:1217) at org.eclipse.swt.widgets.Display.runPendingMessages(Display.java:1198) at org.eclipse.swt.widgets.Display.safeReadAndDispatch(Display.java:1181) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:1173) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1113) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:994) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:156) at org.eclipse.rap.e4.E4EntryPointFactory.createWorkbench(E4EntryPointFactory.java:85) at org.eclipse.rap.e4.E4EntryPointFactory.access$0(E4EntryPointFactory.java:58) at org.eclipse.rap.e4.E4EntryPointFactory$1.createUI(E4EntryPointFactory.java:49) at org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle.createUI(RWTLifeCycle.java:177) at org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle$UIThreadController.run(RWTLifeCycle.java:290) at java.lang.Thread.run(Unknown Source) at org.eclipse.rap.rwt.internal.lifecycle.UIThread.run(UIThread.java:107) !ENTRY org.eclipse.e4.ui.workbench 4 0 2016-02-16 10:09:51.693 !MESSAGE Internal Error !STACK 0 java.lang.RuntimeException: Cycle while computing valueorg.eclipse.e4.ui.internal.workbench.ActiveChildLookupFunction@4d7fe74b at org.eclipse.e4.core.internal.contexts.ValueComputation.get(ValueComputation.java:57) at org.eclipse.e4.core.internal.contexts.EclipseContext.internalGet(EclipseContext.java:226) at org.eclipse.e4.core.internal.contexts.EclipseContext.get(EclipseContext.java:213) at org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRenderer$3.changed(ToolBarManagerRenderer.java:358) at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:114) at org.eclipse.e4.core.internal.contexts.EclipseContext.processScheduled(EclipseContext.java:341) at org.eclipse.e4.core.internal.contexts.EclipseContext.set(EclipseContext.java:356) at org.eclipse.e4.core.internal.contexts.EclipseContext.activate(EclipseContext.java:666) at org.eclipse.e4.core.internal.contexts.EclipseContext.activateBranch(EclipseContext.java:672) at org.eclipse.e4.ui.internal.workbench.PartActivationHistory.activate(PartActivationHistory.java:52) at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:704) at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:639) at org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer.activate(AbstractPartRenderer.java:106) at org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer$9.widgetSelected(StackRenderer.java:1104) at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:263) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:109) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:687) at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:594) at org.eclipse.swt.widgets.Display.executeNextEvent(Display.java:1217) at org.eclipse.swt.widgets.Display.runPendingMessages(Display.java:1198) at org.eclipse.swt.widgets.Display.safeReadAndDispatch(Display.java:1181) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:1173) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1113) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:994) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:156) at org.eclipse.rap.e4.E4EntryPointFactory.createWorkbench(E4EntryPointFactory.java:85) at org.eclipse.rap.e4.E4EntryPointFactory.access$0(E4EntryPointFactory.java:58) at org.eclipse.rap.e4.E4EntryPointFactory$1.createUI(E4EntryPointFactory.java:49) at org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle.createUI(RWTLifeCycle.java:177) at org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle$UIThreadController.run(RWTLifeCycle.java:290) at java.lang.Thread.run(Unknown Source) at org.eclipse.rap.rwt.internal.lifecycle.UIThread.run(UIThread.java:107) !ENTRY org.eclipse.e4.ui.workbench 4 0 2016-02-17 11:34:41.304 !MESSAGE Internal Error !STACK 0 java.lang.RuntimeException: Cycle while computing valueorg.eclipse.e4.ui.internal.services.ActiveContextsFunction@38c223ce at org.eclipse.e4.core.internal.contexts.ValueComputation.get(ValueComputation.java:57) at org.eclipse.e4.core.internal.contexts.EclipseContext.internalGet(EclipseContext.java:226) at org.eclipse.e4.core.internal.contexts.EclipseContext.get(EclipseContext.java:213) at org.eclipse.e4.core.internal.contexts.ContextObjectSupplier.fillArgs(ContextObjectSupplier.java:194) at org.eclipse.e4.core.internal.contexts.ContextObjectSupplier.get(ContextObjectSupplier.java:172) at org.eclipse.e4.core.internal.di.InjectorImpl.resolveArgs(InjectorImpl.java:505) at org.eclipse.e4.core.internal.di.InjectorImpl.resolveArguments(InjectorImpl.java:395) at org.eclipse.e4.core.internal.di.Requestor.resolveArguments(Requestor.java:149) at org.eclipse.e4.core.internal.contexts.ContextObjectSupplier$ContextInjectionListener.update(ContextObjectSupplier.java:89) at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:111) at org.eclipse.e4.core.internal.contexts.EclipseContext.processScheduled(EclipseContext.java:341) at org.eclipse.e4.core.internal.contexts.EclipseContext.set(EclipseContext.java:356) at org.eclipse.e4.core.internal.contexts.EclipseContext.activate(EclipseContext.java:666) at org.eclipse.e4.core.internal.contexts.EclipseContext.activateBranch(EclipseContext.java:672) at org.eclipse.e4.ui.internal.workbench.PartActivationHistory.activate(PartActivationHistory.java:52) at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:704) at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:639) at org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer.activate(AbstractPartRenderer.java:106) at org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer$9.widgetSelected(StackRenderer.java:1104) at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:263) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:109) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:687) at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:594) at org.eclipse.swt.widgets.Display.executeNextEvent(Display.java:1217) at org.eclipse.swt.widgets.Display.runPendingMessages(Display.java:1198) at org.eclipse.swt.widgets.Display.safeReadAndDispatch(Display.java:1181) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:1173) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1113) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:994) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:156) at org.eclipse.rap.e4.E4EntryPointFactory.createWorkbench(E4EntryPointFactory.java:85) at org.eclipse.rap.e4.E4EntryPointFactory.access$0(E4EntryPointFactory.java:58) at org.eclipse.rap.e4.E4EntryPointFactory$1.createUI(E4EntryPointFactory.java:49) at org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle.createUI(RWTLifeCycle.java:177) at org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle$UIThreadController.run(RWTLifeCycle.java:290) at java.lang.Thread.run(Unknown Source) at org.eclipse.rap.rwt.internal.lifecycle.UIThread.run(UIThread.java:107) I logged the threads in ValueComputation.get() and this method is called from two different threads when the exception is thrown.
Yeah and that's strange because ValueComputations are created on a context and we make sure that each E4Application gets its distinct instance. I guess we'd need to make the Exception information smarter to track that down what makes me wonder a bit is that this whole stuff is not thread safe at all so if you have multiple thread in a stand-alone e4 application ValueComputation could fail with the same problem.
Created attachment 259839 [details] More log information
Ivan can you get apply the patch and run the test suite once more this would give use more information why we get into this cycle stuff
(In reply to comment #15) > Ivan can you get apply the patch and run the test suite once more this would > give use more information why we get into this cycle stuff Here it is: !ENTRY org.eclipse.e4.ui.workbench 4 0 2016-02-22 09:58:58.735 !MESSAGE Internal Error !STACK 0 java.lang.RuntimeException: Cycle while computing valueorg.eclipse.e4.ui.internal.workbench.ActivePartLookupFunction@3a71acf3 on WorkbenchContext(EclipseContext@343930481) - computing by null vs cycle threadThread[UIThread [1ec771da],5,main] at org.eclipse.e4.core.internal.contexts.ValueComputation.get(ValueComputation.java:58) at org.eclipse.e4.core.internal.contexts.EclipseContext.internalGet(EclipseContext.java:226) at org.eclipse.e4.core.internal.contexts.EclipseContext.get(EclipseContext.java:213) at org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRenderer$3.changed(ToolBarManagerRenderer.java:358) at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:114) at org.eclipse.e4.core.internal.contexts.EclipseContext.processScheduled(EclipseContext.java:341) at org.eclipse.e4.core.internal.contexts.EclipseContext.set(EclipseContext.java:356) at org.eclipse.e4.core.internal.contexts.EclipseContext.activate(EclipseContext.java:666) at org.eclipse.e4.core.internal.contexts.EclipseContext.activateBranch(EclipseContext.java:672) at org.eclipse.e4.ui.internal.workbench.PartActivationHistory.activate(PartActivationHistory.java:52) at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:704) at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:639) at org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer.activate(AbstractPartRenderer.java:106) at org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer$9.widgetSelected(StackRenderer.java:1104) at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:263) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:109) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:687) at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:594) at org.eclipse.swt.widgets.Display.executeNextEvent(Display.java:1217) at org.eclipse.swt.widgets.Display.runPendingMessages(Display.java:1198) at org.eclipse.swt.widgets.Display.safeReadAndDispatch(Display.java:1181) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:1173) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1113) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:994) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:156) at org.eclipse.rap.e4.E4EntryPointFactory.createWorkbench(E4EntryPointFactory.java:85) at org.eclipse.rap.e4.E4EntryPointFactory.access$0(E4EntryPointFactory.java:58) at org.eclipse.rap.e4.E4EntryPointFactory$1.createUI(E4EntryPointFactory.java:49) at org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle.createUI(RWTLifeCycle.java:177) at org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle$UIThreadController.run(RWTLifeCycle.java:290) at java.lang.Thread.run(Unknown Source) at org.eclipse.rap.rwt.internal.lifecycle.UIThread.run(UIThread.java:107) !ENTRY org.eclipse.e4.ui.workbench 4 0 2016-02-22 09:59:13.437 !MESSAGE Internal Error !STACK 0 java.lang.RuntimeException: Cycle while computing valueorg.eclipse.e4.ui.internal.workbench.ActivePartLookupFunction@30c89b6e on WorkbenchContext(EclipseContext@2046250797) - computing by null vs cycle threadThread[UIThread [2d25fd88],5,main] at org.eclipse.e4.core.internal.contexts.ValueComputation.get(ValueComputation.java:58) at org.eclipse.e4.core.internal.contexts.EclipseContext.internalGet(EclipseContext.java:226) at org.eclipse.e4.core.internal.contexts.EclipseContext.get(EclipseContext.java:213) at org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRenderer$3.changed(ToolBarManagerRenderer.java:358) at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:114) at org.eclipse.e4.core.internal.contexts.EclipseContext.processScheduled(EclipseContext.java:341) at org.eclipse.e4.core.internal.contexts.EclipseContext.set(EclipseContext.java:356) at org.eclipse.e4.core.internal.contexts.EclipseContext.activate(EclipseContext.java:666) at org.eclipse.e4.core.internal.contexts.EclipseContext.activateBranch(EclipseContext.java:672) at org.eclipse.e4.ui.internal.workbench.PartActivationHistory.activate(PartActivationHistory.java:52) at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:704) at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:639) at org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer.activate(AbstractPartRenderer.java:106) at org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer$9.widgetSelected(StackRenderer.java:1104) at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:263) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:109) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:687) at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:594) at org.eclipse.swt.widgets.Display.executeNextEvent(Display.java:1217) at org.eclipse.swt.widgets.Display.runPendingMessages(Display.java:1198) at org.eclipse.swt.widgets.Display.safeReadAndDispatch(Display.java:1181) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:1173) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1113) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:994) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:156) at org.eclipse.rap.e4.E4EntryPointFactory.createWorkbench(E4EntryPointFactory.java:85) at org.eclipse.rap.e4.E4EntryPointFactory.access$0(E4EntryPointFactory.java:58) at org.eclipse.rap.e4.E4EntryPointFactory$1.createUI(E4EntryPointFactory.java:49) at org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle.createUI(RWTLifeCycle.java:177) at org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle$UIThreadController.run(RWTLifeCycle.java:290) at java.lang.Thread.run(Unknown Source) at org.eclipse.rap.rwt.internal.lifecycle.UIThread.run(UIThread.java:107) !ENTRY org.eclipse.e4.ui.workbench 4 0 2016-02-22 09:59:16.437 !MESSAGE Internal Error !STACK 0 java.lang.RuntimeException: Cycle while computing valueorg.eclipse.e4.ui.internal.workbench.ActivePartLookupFunction@163f4e3f on WorkbenchContext(EclipseContext@734121323) - computing by null vs cycle threadThread[UIThread [dac0fb2],5,main] at org.eclipse.e4.core.internal.contexts.ValueComputation.get(ValueComputation.java:58) at org.eclipse.e4.core.internal.contexts.EclipseContext.internalGet(EclipseContext.java:226) at org.eclipse.e4.core.internal.contexts.EclipseContext.get(EclipseContext.java:213) at org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRenderer$3.changed(ToolBarManagerRenderer.java:358) at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:114) at org.eclipse.e4.core.internal.contexts.EclipseContext.processScheduled(EclipseContext.java:341) at org.eclipse.e4.core.internal.contexts.EclipseContext.set(EclipseContext.java:356) at org.eclipse.e4.core.internal.contexts.EclipseContext.activate(EclipseContext.java:666) at org.eclipse.e4.core.internal.contexts.EclipseContext.activateBranch(EclipseContext.java:672) at org.eclipse.e4.ui.internal.workbench.PartActivationHistory.activate(PartActivationHistory.java:52) at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:704) at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:639) at org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer.activate(AbstractPartRenderer.java:106) at org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer$9.widgetSelected(StackRenderer.java:1104) at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:263) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:109) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:687) at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:594) at org.eclipse.swt.widgets.Display.executeNextEvent(Display.java:1217) at org.eclipse.swt.widgets.Display.runPendingMessages(Display.java:1198) at org.eclipse.swt.widgets.Display.safeReadAndDispatch(Display.java:1181) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:1173) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1113) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:994) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:156) at org.eclipse.rap.e4.E4EntryPointFactory.createWorkbench(E4EntryPointFactory.java:85) at org.eclipse.rap.e4.E4EntryPointFactory.access$0(E4EntryPointFactory.java:58) at org.eclipse.rap.e4.E4EntryPointFactory$1.createUI(E4EntryPointFactory.java:49) at org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle.createUI(RWTLifeCycle.java:177) at org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle$UIThreadController.run(RWTLifeCycle.java:290) at java.lang.Thread.run(Unknown Source) at org.eclipse.rap.rwt.internal.lifecycle.UIThread.run(UIThread.java:107)
Created attachment 259856 [details] More log information (2nd try)
Comment on attachment 259856 [details] More log information (2nd try) Forget that patch too early
Current findings by instrumenting code (need to stop for now): ... Initializing org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRenderer@62f63f34 on context WorkbenchContext@6a7bed7b on thread Thread[UIThread [3baa6482],5,main] Initializing org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRenderer@1cbcb0c on context WorkbenchContext@6df1aae8 on thread Thread[UIThread [66e0778d],5,main] .... Initializing org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRenderer@1dbaeadd on context WorkbenchContext@7daad0ed on thread Thread[UIThread [2e14525a],5,main] java.lang.RuntimeException: Cycle while computing valueorg.eclipse.e4.ui.internal.workbench.ActivePartLookupFunction@5b4f492e on WorkbenchContext(EclipseContext@7daad0ed) - computing by Thread[UIThread [3baa6482],5,main] vs cycle threadThread[UIThread [66e0778d],5,main] at org.eclipse.e4.core.internal.contexts.ValueComputation.get(ValueComputation.java:60) at org.eclipse.e4.core.internal.contexts.EclipseContext.internalGet(EclipseContext.java:226) at org.eclipse.e4.core.internal.contexts.EclipseContext.get(EclipseContext.java:213) at org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRenderer$3.changed(ToolBarManagerRenderer.java:366) at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:114) at org.eclipse.e4.core.internal.contexts.EclipseContext.processScheduled(EclipseContext.java:341) at org.eclipse.e4.core.internal.contexts.EclipseContext.set(EclipseContext.java:356) at org.eclipse.e4.core.internal.contexts.EclipseContext.activate(EclipseContext.java:666) at org.eclipse.e4.core.internal.contexts.EclipseContext.activateBranch(EclipseContext.java:672) at org.eclipse.e4.ui.internal.workbench.PartActivationHistory.activate(PartActivationHistory.java:52) at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:704) at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:639) at org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer.activate(AbstractPartRenderer.java:106) at org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer$9.widgetSelected(StackRenderer.java:1104) at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:263) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:109) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:687) at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:594) at org.eclipse.swt.widgets.Display.executeNextEvent(Display.java:1217) at org.eclipse.swt.widgets.Display.runPendingMessages(Display.java:1198) at org.eclipse.swt.widgets.Display.safeReadAndDispatch(Display.java:1181) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:1173) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1113) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:994) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:156) at org.eclipse.rap.e4.E4EntryPointFactory.createWorkbench(E4EntryPointFactory.java:85) at org.eclipse.rap.e4.E4EntryPointFactory.access$0(E4EntryPointFactory.java:58) at org.eclipse.rap.e4.E4EntryPointFactory$1.createUI(E4EntryPointFactory.java:49) at org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle.createUI(RWTLifeCycle.java:177) at org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle$UIThreadController.run(RWTLifeCycle.java:290) at java.lang.Thread.run(Thread.java:745) at org.eclipse.rap.rwt.internal.lifecycle.UIThread.run(UIThread.java:107) As one can see we are creating distinct instances for each ToolbarManagerRenderer and then register RATs. If you now look closely at Exception you notice: * We have concurrent computations from UIThread [3baa6482] and UIThread [66e0778d] on EclipseContext@7daad0ed * But EclipseContext@7daad0ed is the context just intializing the ToolbarRenderer and is bound too UIThread [2e14525a]
I have not tracked down how and why but i think the problem is that we still share the root IEclipseContext between all instances and then the first offending access from an invalid thread is coming from an branch activation. If I make sure that each and every instance gets a distinct root context (EclipseContextOSGi) everything runs nice and smooth. So to make multi-instance e4 applications possible we need to request a new API from the EclipseContextFactory to create OSGi-Contexts at will and not getting a cached instance, the caller is then responsible to dipose the context at the end of the session.
Proposed additional platform API in EclipseContextFactory as Gerrit change https://git.eclipse.org/r/#/c/67204/
Ivan can you please update your patch to align with the format used in platform which is "Bug 479778 - [DI] Exceptions with concurrent user sessions" as the first line. For those following and don't know what we are proposing doing is that we (Ivan and me) tracked down the problem of the cycle stuff to the fact that IEclipseContext#activeBranch bubbles down to the ONE AND ONLY ServiceContext that ALL our RAP E4Application instances share as of today because the only way to bootstrap it is with the currently caching getServiceContext() call, as we can not change the semantics of behavior of that API because people rely on the fact that they get back the very same context all time we propose the new API which will be used by the RAP implementation when bootstrapping the framework.
Gerrit change https://git.eclipse.org/r/67204 was merged to [master]. Commit: http://git.eclipse.org/c/platform/eclipse.platform.runtime.git/commit/?id=890e64c67c6ba222eb9e777e3e5e42e4b5dbf8d0
released the patch