XmlTagNameSynchronizer$TagNameSynchronizer disposal problem when testing XML documents

Hi!

I’ve started to upgrade one of my plugins to build on 2024.2.5 (and tried 2024.3 as well), and ran into a problem regarding testing XML files.

I have many tests (for line marker providers, file icon providers, actions) that create editors for XML test documents and check some stuff in them, e.g. getFixture().configureByFile(...).

My tests subclass LightJavaCodeInsightFixtureTestCase5 (which may or may not be a good idea for XML documents, but it has worked without issue until now).

However, when I execute my entire test suite (tests individually work fine), certain, even unrelated, tests (not necessarily the same ones on different runs) fail with the exception below.

This was not an issue when the plugin was built on 2024.1.*. Unfortunately, I don’t have any clue how this could be solved. I tried to look into disabling com.intellij.codeInsight.editorActions.XmlTagNameSynchronizer.MyEditorFactoryListener because it doesn’t seem to be necessary for my tests, but with no luck.

I’m curious if anyone has run into this, and has any advice on how to handle it.

1 uncaught exceptions:
1) 
com.intellij.testFramework.TestLoggerFactory$TestLoggerAssertionError: Worker exited due to exception
	at com.intellij.testFramework.TestLoggerFactory$TestLogger.error(TestLoggerFactory.java:460)
	at com.intellij.openapi.diagnostic.Logger.error(Logger.java:423)
	at com.intellij.util.concurrency.AppScheduledExecutorService$BackendThreadPoolExecutor.afterExecute(AppScheduledExecutorService.java:164)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1147)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:735)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:732)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:732)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: com.intellij.testFramework.TestLoggerFactory$TestLoggerAssertionError: Sorry but parent: newDisposable (class com.intellij.openapi.util.Disposer$1) has already been disposed (see the cause for stacktrace) so the child: com.intellij.codeInsight.editorActions.XmlTagNameSynchronizer$TagNameSynchronizer@75bd8c4 (class com.intellij.codeInsight.editorActions.XmlTagNameSynchronizer$TagNameSynchronizer) will never be disposed
	at com.intellij.testFramework.TestLoggerFactory$TestLogger.error(TestLoggerFactory.java:460)
	at com.intellij.openapi.diagnostic.Logger.error(Logger.java:436)
	at org.jetbrains.concurrency.Promises__PromiseKt.errorIfNotMessage(promise.kt:238)
	at org.jetbrains.concurrency.Promises.errorIfNotMessage(Unknown Source)
	at org.jetbrains.concurrency.AsyncPromise.setError(AsyncPromise.kt:201)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.setError(NonBlockingReadActionImpl.java:352)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.insideReadAction(NonBlockingReadActionImpl.java:644)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.lambda$attemptComputation$4(NonBlockingReadActionImpl.java:581)
	at com.intellij.openapi.application.impl.AnyThreadWriteThreadingSupport.tryRunReadAction(AnyThreadWriteThreadingSupport.kt:351)
	at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:971)
	at com.intellij.openapi.progress.util.ProgressIndicatorUtils.lambda$runInReadActionWithWriteActionPriority$0(ProgressIndicatorUtils.java:95)
	at com.intellij.openapi.progress.util.ProgressIndicatorUtilService.runActionAndCancelBeforeWrite(ProgressIndicatorUtilService.java:66)
	at com.intellij.openapi.progress.util.ProgressIndicatorUtils.runActionAndCancelBeforeWrite(ProgressIndicatorUtils.java:157)
	at com.intellij.openapi.progress.util.ProgressIndicatorUtils.lambda$runWithWriteActionPriority$1(ProgressIndicatorUtils.java:140)
	at com.intellij.openapi.progress.ProgressManager.lambda$runProcess$0(ProgressManager.java:98)
	at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$1(CoreProgressManager.java:223)
	at com.intellij.platform.diagnostic.telemetry.helpers.TraceKt.use(trace.kt:45)
	at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$2(CoreProgressManager.java:222)
	at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$executeProcessUnderProgress$14(CoreProgressManager.java:674)
	at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:749)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computeUnderProgress(CoreProgressManager.java:705)
	at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:673)
	at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:79)
	at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:203)
	at com.intellij.openapi.progress.ProgressManager.runProcess(ProgressManager.java:98)
	at com.intellij.openapi.progress.util.ProgressIndicatorUtils.runWithWriteActionPriority(ProgressIndicatorUtils.java:137)
	at com.intellij.openapi.progress.util.ProgressIndicatorUtils.runInReadActionWithWriteActionPriority(ProgressIndicatorUtils.java:95)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.attemptComputation(NonBlockingReadActionImpl.java:581)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.lambda$transferToBgThread$1(NonBlockingReadActionImpl.java:480)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.lambda$transferToBgThread$2(NonBlockingReadActionImpl.java:495)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	... 6 more
Caused by: com.intellij.util.IncorrectOperationException: Sorry but parent: newDisposable (class com.intellij.openapi.util.Disposer$1) has already been disposed (see the cause for stacktrace) so the child: com.intellij.codeInsight.editorActions.XmlTagNameSynchronizer$TagNameSynchronizer@75bd8c4 (class com.intellij.codeInsight.editorActions.XmlTagNameSynchronizer$TagNameSynchronizer) will never be disposed
	at com.intellij.openapi.util.ObjectTree.register(ObjectTree.java:43)
	at com.intellij.openapi.util.Disposer.register(Disposer.java:156)
	at com.intellij.codeInsight.editorActions.XmlTagNameSynchronizer$TagNameSynchronizer.listenForDocumentChanges(XmlTagNameSynchronizer.java:183)
	at com.intellij.codeInsight.editorActions.XmlTagNameSynchronizer.lambda$createSynchronizerFor$0(XmlTagNameSynchronizer.java:84)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$OTelMonitor.callWrapped(NonBlockingReadActionImpl.java:857)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$OTelMonitor$MonitoredComputation.call(NonBlockingReadActionImpl.java:889)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.insideReadAction(NonBlockingReadActionImpl.java:618)
	... 30 more
Caused by: java.lang.Throwable
	at com.intellij.openapi.util.ObjectTree.runWithTrace(ObjectTree.java:103)
	at com.intellij.openapi.util.ObjectTree.executeAll(ObjectTree.java:163)
	at com.intellij.openapi.util.Disposer.dispose(Disposer.java:205)
	at com.intellij.openapi.util.Disposer.dispose(Disposer.java:193)
	at com.intellij.openapi.editor.impl.EditorImpl.lambda$release$20(EditorImpl.java:1155)
	at com.intellij.openapi.editor.impl.EditorImpl.executeNonCancelableBlock(EditorImpl.java:1114)
	at com.intellij.openapi.editor.impl.EditorImpl.release(EditorImpl.java:1121)
	at com.intellij.openapi.editor.impl.EditorFactoryImpl.releaseEditor(EditorFactoryImpl.kt:238)
	at com.intellij.openapi.fileEditor.impl.TestEditorManagerImpl.closeFile(TestEditorManagerImpl.kt:353)
	at com.intellij.openapi.fileEditor.impl.TestEditorManagerImpl.closeAllFiles(TestEditorManagerImpl.kt:260)
	at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.closeOpenFiles(CodeInsightTestFixtureImpl.java:1502)
	at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.lambda$tearDown$39(CodeInsightTestFixtureImpl.java:1457)
	at com.intellij.testFramework.EdtTestUtil.lambda$runInEdtAndWait$5(EdtTestUtil.java:91)
	at com.intellij.openapi.application.TransactionGuardImpl.runWithWritingAllowed(TransactionGuardImpl.java:236)
	at com.intellij.openapi.application.TransactionGuardImpl.access$100(TransactionGuardImpl.java:25)
	at com.intellij.openapi.application.TransactionGuardImpl$1.run(TransactionGuardImpl.java:198)
	at com.intellij.openapi.application.impl.AnyThreadWriteThreadingSupport.runIntendedWriteActionOnCurrentThread$lambda$2(AnyThreadWriteThreadingSupport.kt:217)
	at com.intellij.openapi.application.impl.AnyThreadWriteThreadingSupport.runWriteIntentReadAction(AnyThreadWriteThreadingSupport.kt:128)
	at com.intellij.openapi.application.impl.AnyThreadWriteThreadingSupport.runIntendedWriteActionOnCurrentThread(AnyThreadWriteThreadingSupport.kt:216)
	at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:842)
	at com.intellij.openapi.application.impl.ApplicationImpl$2.run(ApplicationImpl.java:421)
	at com.intellij.openapi.application.impl.AppImplKt.rethrowExceptions$lambda$2(appImpl.kt:57)
	at com.intellij.util.concurrency.ChildContext$runInChildContext$1.invoke(propagation.kt:101)
	at com.intellij.util.concurrency.ChildContext$runInChildContext$1.invoke(propagation.kt:101)
	at com.intellij.util.concurrency.ChildContext.runInChildContext(propagation.kt:107)
	at com.intellij.util.concurrency.ChildContext.runInChildContext(propagation.kt:101)
	at com.intellij.util.concurrency.ContextRunnable.run(ContextRunnable.java:27)
	at com.intellij.openapi.application.impl.AppImplKt.rethrowExceptions$lambda$3(appImpl.kt:68)
	at com.intellij.openapi.application.impl.LaterInvocator$1.run(LaterInvocator.java:102)
	at com.intellij.openapi.application.impl.FlushQueue.runNextEvent(FlushQueue.java:117)
	at com.intellij.openapi.application.impl.FlushQueue.flushNow(FlushQueue.java:43)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:781)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:728)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:750)
	at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.kt:675)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.kt:573)
	at com.intellij.ide.IdeEventQueue.dispatchEvent$lambda$18$lambda$17$lambda$16$lambda$15(IdeEventQueue.kt:355)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:857)
	at com.intellij.ide.IdeEventQueue.dispatchEvent$lambda$18$lambda$17$lambda$16(IdeEventQueue.kt:354)
	at com.intellij.ide.IdeEventQueueKt.performActivity$lambda$2$lambda$1(IdeEventQueue.kt:1045)
	at com.intellij.openapi.application.WriteIntentReadAction.lambda$run$0(WriteIntentReadAction.java:24)
	at com.intellij.openapi.application.impl.AnyThreadWriteThreadingSupport.runWriteIntentReadAction(AnyThreadWriteThreadingSupport.kt:128)
	at com.intellij.openapi.application.impl.ApplicationImpl.runWriteIntentReadAction(ApplicationImpl.java:916)
	at com.intellij.openapi.application.WriteIntentReadAction.compute(WriteIntentReadAction.java:55)
	at com.intellij.openapi.application.WriteIntentReadAction.run(WriteIntentReadAction.java:23)
	at com.intellij.ide.IdeEventQueueKt.performActivity$lambda$2(IdeEventQueue.kt:1045)
	at com.intellij.ide.IdeEventQueueKt.performActivity$lambda$3(IdeEventQueue.kt:1054)
	at com.intellij.openapi.application.TransactionGuardImpl.performActivity(TransactionGuardImpl.java:117)
	at com.intellij.ide.IdeEventQueueKt.performActivity(IdeEventQueue.kt:1054)
	at com.intellij.ide.IdeEventQueue.dispatchEvent$lambda$18(IdeEventQueue.kt:349)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.kt:395)
	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)

Thank you!

This seems to be a known issue (https://youtrack.jetbrains.com/issue/IJPL-166144, non-public ATM).

Ah, it is known then, thank you.
Is there a workaround you could suggest until it gets fixed?

Unfortunately, no workarounds are available.

I have an open issue against XmlTagNameSynchronizer as well, is it possible to make that issue public to see if they need to be linked?

The non-public issue is strictly about disposal issues.