'Write access is allowed from event dispatch thread only' error while running IdeaTestCase
Here is snip of testcase:
public class RefreshCommandTest extends IdeaTestCase {
...
@Override
protected void setUp() throws Exception {
super.setUp();
...
}
}
Here is stacktrace:
ERROR: Write access is allowed from event dispatch thread only
java.lang.Throwable
at com.intellij.openapi.diagnostic.Logger.error(Logger.java:55)
at com.intellij.openapi.application.impl.ApplicationImpl.assertIsDispatchThread(ApplicationImpl.java:952)
at com.intellij.openapi.application.impl.ApplicationImpl.assertCanRunWriteAction(ApplicationImpl.java:932)
at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:805)
at com.intellij.testFramework.PlatformTestCase.setUpJdk(PlatformTestCase.java:458)
at com.intellij.testFramework.PlatformTestCase.setUpProject(PlatformTestCase.java:197)
at com.intellij.testFramework.PlatformTestCase.setUp(PlatformTestCase.java:162)
at com...RefreshCommandTest.setUp(RefreshCommandTest.java:43)
at com.intellij.testFramework.PlatformTestCase$5.run(PlatformTestCase.java:503)
at com...RefreshCommandTest.runBareRunnable(RefreshCommandTest.java:64)
at com.intellij.testFramework.PlatformTestCase.runBareImpl(PlatformTestCase.java:532)
at com.intellij.testFramework.PlatformTestCase.runBare(PlatformTestCase.java:476)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.textui.TestRunner.doRun(TestRunner.java:116)
at com.intellij.junit3.JUnit3IdeaTestRunner.doRun(JUnit3IdeaTestRunner.java:108)
at junit.textui.TestRunner.doRun(TestRunner.java:109)
at com.intellij.junit3.JUnit3IdeaTestRunner.startRunnerWithArgs(JUnit3IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:192)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:115)
details:
Current thread: Thread[main,5,main] 24130647
Our dispatch thread:Thread[AWT-EventQueue-0,6,main] 17390721
SystemEventQueueThread: Thread[AWT-EventQueue-0,6,main] 17390721
- Access is allowed from event dispatch thread only.
Any idea on how to fix this?
Please sign in to leave a comment.
Hello chandra,
This should be fixed by running the initialization code in the event dispatch
thread. The test framework does this by default, but it looks like you've
overridden some parts of it and thus disabled this behavior.
--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"
Dmitry,
thanks for the hint.
I am debugging a test which runs outside AWT event thread [here is related post on how to do this: http://devnet.jetbrains.net/message/5176841]
This test sets jdk which seems to work fine in Intellij-9, where as this is failing when run against Intellij-10.
This test has overriden the following methods:
protected void runBareRunnable(Runnable runnable) throws Throwable {
runnable.run();
}
protected void invokeTestRunnable(Runnable runnable) throws Exception {
runnable.run();
}
here is the test method causing the problem:
private static Sdk createJdk(final String jdkName, final String javaHome) {
return UiUtil.runWriteAction(ApplicationManager.getApplication(),
new Computable<Sdk>() {
public Sdk compute() {
ProjectJdkTable jdkTable = ProjectJdkTable.getInstance();
JavaSdk sdkFactory = JavaSdk.getInstance();
Sdk myJdk = sdkFactory.createJdk(jdkName, javaHome);
jdkTable.addJdk(myJdk);
return myJdk;
}
});
}
where UiUtil.runWriteAction() returns Computable.compute(); [when run in unit test mode]
Any idea on how to add JDK to projects from non-AWT threads?
Thanks,
Chandra
Hello chandra,
There is no way to perform a write action from outside the AWT event thread.
--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"
Hi Dmitry,
"This should be fixed by running the initialization code in the event dispatch thread. The test framework does this by default..."
Could you give me a pointer to where this is done? I'd like to replicate this in JUnit 4 tests and I couldn't see how to do it.
Hello Colin,
UsefulTestCase.runBare()
--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"
Great, thanks Dmitry.
ApplicationImpl.assertIsDispatchThread() has been changed between 9.0.4 and 10.0.3.
In 9.0.4 assertIsDispatchThread() is as follows:
private void assertIsDispatchThread(String message) {
if (myTestModeFlag || myHeadlessMode || ShutDownTracker.isShutdownHookRunning()) return;
final Thread currentThread = Thread.currentThread();
if (ourDispatchThread == currentThread) return;
if (EventQueue.isDispatchThread()) {
ourDispatchThread = currentThread;
}
if (ourDispatchThread == currentThread) return;
Integer safeCounter = ourEdtSafe.get();
if (safeCounter != null && safeCounter > 0) return;
LOG.error(message,
"Current thread: " + describe(Thread.currentThread()),
"Our dispatch thread:" + describe(ourDispatchThread),
"SystemEventQueueThread: " + describe(getEventQueueThread()));
}
It returns when application is in test mode.
Where as in 10.0.3 assertIsDispatchThread() is as follows:
private static void assertIsDispatchThread(String message) {
if (ShutDownTracker.isShutdownHookRunning()) return;
final Thread currentThread = Thread.currentThread();
if (ourDispatchThread == currentThread) return;
if (EventQueue.isDispatchThread()) {
ourDispatchThread = currentThread;
}
if (ourDispatchThread == currentThread) return;
Integer safeCounter = ourEdtSafe.get();
if (safeCounter != null && safeCounter > 0) return;
LOG.error(message,
"Current thread: " + describe(Thread.currentThread()),
"Our dispatch thread:" + describe(ourDispatchThread),
"SystemEventQueueThread: " + describe(getEventQueueThread()));
}
test mode related code is removed and this method is now made static.
Is there any reason for not allowing write action from outside of AWT event thread (even for tests)?
Thx,
Chandra
Hello chandra,
The reason for the change was to make the tests closer to real life. We want
our tests to test the actual behavior of IntelliJ IDEA, not of some artificial
construct that does not exist on our users' PCs.
--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"
Hi Dimitry,
Bringing the discussion back to our original problem.
We want to test certain actions on the event Queue by waiting for those actions as described in http://devnet.jetbrains.net/message/5176841
The default model of IdeaTestCase does not allow that since tests run in the AWT event thread.
Please advise on how we can write tests that wait for events on the queue in Intellij 10.x since without that we cannot port our plugin tests to Intellij 10.
thanks
Siddharth