IllegalStateException: StructureTreeModel is used from unexpected thread
Answered
Hi, I am in process of upgrading a plugin from IC-2022.3.3 to IC-2024.1.5
One of the breaking changes is we used to extend FilteringTreeBuilder which has ben removed, and now we instead as per Deprecated instruction use FilteringTreeModel. However, there is an issue, the tree never renders and we have 11 stacktraces that are different in the logs but all have JTree.setModel in there, here is an example below. Any ideas ?
2024-11-12 21:42:44,950 [ 55055] WARN - #c.i.u.t.StructureTreeModel - StructureTreeModel is used from unexpected thread
java.lang.IllegalStateException: StructureTreeModel is used from unexpected thread
at com.intellij.ui.tree.StructureTreeModel.isValidThread(StructureTreeModel.java:110)
at com.intellij.ui.tree.StructureTreeModel.getRoot(StructureTreeModel.java:312)
at com.intellij.ui.tree.StructureTreeModel.getRoot(StructureTreeModel.java:37)
at java.desktop/javax.swing.JTree.setModel(JTree.java:940)
at com.mycompany.upgrade.plugin.merge.tree.view.MergeTreeBuilder.<init>(MergeTreeBuilder.java:30)
at com.mycompany.upgrade.plugin.merge.tree.view.MergeTreePane.<init>(MergeTreePane.java:95)
at com.mycompany.upgrade.plugin.merge.tree.view.MergeDiaryPanel.<init>(MergeDiaryPanel.java:52)
at com.mycompany.upgrade.plugin.merge.MergeDiaryViewImpl.<init>(MergeDiaryViewImpl.java:39)
at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
at com.intellij.platform.instanceContainer.instantiation.InstantiateKt$instantiate$2.invoke(instantiate.kt:49)
at com.intellij.platform.instanceContainer.instantiation.InstantiateKt$instantiate$2.invoke(instantiate.kt:42)
at com.intellij.platform.instanceContainer.instantiation.InstantiateKt.instantiate(instantiate.kt:308)
at com.intellij.platform.instanceContainer.instantiation.InstantiateKt.instantiate(instantiate.kt:42)
at com.intellij.serviceContainer.ServiceInstanceInitializer.createInstance$suspendImpl(ServiceInstanceInitializer.kt:31)
at com.intellij.serviceContainer.ServiceInstanceInitializer.createInstance(ServiceInstanceInitializer.kt)
at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder$initialize$1$1.invokeSuspend(LazyInstanceHolder.kt:162)
at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder$initialize$1$1.invoke(LazyInstanceHolder.kt)
at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder$initialize$1$1.invoke(LazyInstanceHolder.kt)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:78)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:167)
at kotlinx.coroutines.BuildersKt.withContext(Unknown Source)
at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder$initialize$1.invokeSuspend(LazyInstanceHolder.kt:160)
at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder$initialize$1.invoke(LazyInstanceHolder.kt)
at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder$initialize$1.invoke(LazyInstanceHolder.kt)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startCoroutineUndispatched(Undispatched.kt:44)
at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:112)
at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56)
at kotlinx.coroutines.BuildersKt.launch(Unknown Source)
at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder.initialize(LazyInstanceHolder.kt:145)
at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder.access$initialize(LazyInstanceHolder.kt:13)
at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder.tryInitialize(LazyInstanceHolder.kt:135)
at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder.getInstance(LazyInstanceHolder.kt:95)
at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder.getInstanceInCallerContext$suspendImpl(LazyInstanceHolder.kt:87)
at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder.getInstanceInCallerContext(LazyInstanceHolder.kt)
at com.intellij.serviceContainer.ComponentManagerImplKt$getOrCreateInstanceBlocking$3.invokeSuspend(ComponentManagerImpl.kt:1548)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:280)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at com.intellij.serviceContainer.ComponentManagerImplKt$runBlockingInitialization$1.invoke(ComponentManagerImpl.kt:1636)
at com.intellij.serviceContainer.ComponentManagerImplKt$runBlockingInitialization$1.invoke(ComponentManagerImpl.kt:1627)
at com.intellij.openapi.progress.ContextKt.prepareThreadContext(context.kt:83)
at com.intellij.serviceContainer.ComponentManagerImplKt.runBlockingInitialization(ComponentManagerImpl.kt:1627)
at com.intellij.serviceContainer.ComponentManagerImplKt.getOrCreateInstanceBlocking(ComponentManagerImpl.kt:1547)
at com.intellij.serviceContainer.ComponentManagerImpl.doGetService(ComponentManagerImpl.kt:754)
at com.intellij.serviceContainer.ComponentManagerImpl.getService(ComponentManagerImpl.kt:698)
at com.mycompany.upgrade.plugin.manager.UpgradeServiceManager.get(UpgradeServiceManager.java:106)
at com.mycompany.upgrade.plugin.manager.UpgradeServiceManager.getMergeDiaryView(UpgradeServiceManager.java:87)
at com.mycompany.upgrade.plugin.merge.MergeDiaryWindowFactory.createToolWindowContent(MergeDiaryWindowFactory.java:22)
at com.intellij.openapi.wm.impl.ToolWindowImpl.createContentIfNeeded(ToolWindowImpl.kt:596)
at com.intellij.openapi.wm.impl.ToolWindowImpl.scheduleContentInitializationIfNeeded$intellij_platform_ide_impl(ToolWindowImpl.kt:575)
at com.intellij.openapi.wm.impl.ToolWindowManagerImpl.doShowWindow(ToolWindowManagerImpl.kt:1036)
at com.intellij.openapi.wm.impl.ToolWindowManagerImpl.showToolWindowImpl(ToolWindowManagerImpl.kt:970)
at com.intellij.openapi.wm.impl.ToolWindowManagerImpl.activateToolWindow$intellij_platform_ide_impl(ToolWindowManagerImpl.kt:670)
at com.intellij.openapi.wm.impl.ToolWindowManagerImpl.activateToolWindow$intellij_platform_ide_impl$default(ToolWindowManagerImpl.kt:639)
at com.intellij.openapi.wm.impl.ToolWindowManagerImpl.activated$intellij_platform_ide_impl(ToolWindowManagerImpl.kt:2301)
at com.intellij.toolWindow.StripeButton._init_$lambda$0(StripeButton.kt:62)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
at java.desktop/javax.swing.JToggleButton$ToggleButtonModel.setPressed(JToggleButton.java:411)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:298)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6657)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3385)
at com.intellij.toolWindow.StripeButton.processMouseEvent(StripeButton.kt:247)
at java.desktop/java.awt.Component.processEvent(Component.java:6422)
at java.desktop/java.awt.Container.processEvent(Container.java:2266)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5027)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4855)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4969)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4583)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4524)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2809)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4855)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:794)
at java.desktop/java.awt.EventQueue$3.run(EventQueue.java:739)
at java.desktop/java.awt.EventQueue$3.run(EventQueue.java:733)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:766)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:764)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:763)
at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.kt:699)
at com.intellij.ide.IdeEventQueue.dispatchMouseEvent(IdeEventQueue.kt:638)
at com.intellij.ide.IdeEventQueue._dispatchEvent$lambda$10(IdeEventQueue.kt:584)
at com.intellij.openapi.application.impl.RwLockHolder.runWithEnabledImplicitRead(RwLockHolder.kt:138)
at com.intellij.openapi.application.impl.RwLockHolder.runWithImplicitRead(RwLockHolder.kt:129)
at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.kt:584)
at com.intellij.ide.IdeEventQueue.access$_dispatchEvent(IdeEventQueue.kt:77)
at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1$1.compute(IdeEventQueue.kt:362)
at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1$1.compute(IdeEventQueue.kt:361)
at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:843)
at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1.invoke(IdeEventQueue.kt:361)
at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1.invoke(IdeEventQueue.kt:356)
at com.intellij.ide.IdeEventQueueKt.performActivity$lambda$1(IdeEventQueue.kt:1022)
at com.intellij.openapi.application.TransactionGuardImpl.performActivity(TransactionGuardImpl.java:114)
at com.intellij.ide.IdeEventQueueKt.performActivity(IdeEventQueue.kt:1022)
at com.intellij.ide.IdeEventQueue.dispatchEvent$lambda$7(IdeEventQueue.kt:356)
at com.intellij.openapi.application.impl.RwLockHolder.runIntendedWriteActionOnCurrentThread(RwLockHolder.kt:209)
at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:830)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.kt:398)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:207)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:92)
Please sign in to leave a comment.
It seems that you're trying to use a
StructureTreeModel
directly on aTree
. This is not supported in most cases, asStructureTreeModel
is typically slow and involves background operations prohibited on the EDT. That's why you normally wrap it into anAsyncTreeModel
which serves as a bridge, delegating calls to the background model to background threads and then reporting the results back to the EDT.In the case your model doesn't really involve any background operations (I/O, read actions, PSI or VFS access, etc.), you may try to configure
StructureTreeModel
accordingly by passingInvoker.forEventDispatchThread
to it.Using
AsyncTreeModel
did the trick. Instead of doingtree.setModel(_treeModel)
now changed totree.setModel(new AsyncTreeModel(_treeModel, this))
thank you Sergei !