SetupJDKFix fails in LightCodeInsightFixtureTestCase

Answered

Hi,

I am trying to write my first LightCodeInsightFixtureTestCases. Every time I invoke an IntentionAction via 

myFixture.launchAction(intention);

I get a not so nice exception [1]. After digging a bit I found out that SetupJdkQuickFix accesses the ProjectSettingsService (whose instance is of type IdeaProjectSettingsService), whose chooseAndSetJdk method accesses the main window frame. As the test runs headless this frame is null.

Unfortunately the fix tries to construct a JdkChooserPanel, which in turn is a DialogWrapper. The super(parent, true) call resolves to super(null, true). As parent may not be null IntelliJ throws a IllegalArgumentException.

Obviously I am doing something wrong. Is there any chance to stop Java from evaluating this annotation? I could not even find by whom that exception is thrown, as the thrower does not appear in the stack trace.

Is there any kind of different solution?

Thanks,

Matthias

 

[1].

java.lang.IllegalArgumentException: Argument for @NotNull parameter 'parent' of com/intellij/openapi/ui/DialogWrapper.<init> must not be null

at com.intellij.openapi.ui.DialogWrapper.<init>(DialogWrapper.java)
at com.intellij.ide.util.projectWizard.JdkChooserPanel$MyDialog.<init>(JdkChooserPanel.java:257)
at com.intellij.ide.util.projectWizard.JdkChooserPanel.showDialog(JdkChooserPanel.java:220)
at com.intellij.ide.util.projectWizard.JdkChooserPanel.chooseAndSetJDK(JdkChooserPanel.java:242)
at com.intellij.openapi.roots.ui.configuration.IdeaProjectSettingsService.chooseAndSetSdk(IdeaProjectSettingsService.java:164)
at com.intellij.codeInsight.daemon.impl.quickfix.SetupJDKFix.invoke(SetupJDKFix.java:68)
at com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler$2.run(ShowIntentionActionsHandler.java:189)
at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:124)
at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:99)
at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:85)
at com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler.chooseActionAndInvoke(ShowIntentionActionsHandler.java:210)
at com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler.chooseActionAndInvoke(ShowIntentionActionsHandler.java:166)
at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.launchAction(CodeInsightTestFixtureImpl.java:737)
at org.jetbrains.plugins.akdb.jboss5.EJBInjectOnConcreteClassTest.testbla(EJBInjectOnConcreteClassTest.java:36)
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 junit.framework.TestCase.runTest(TestCase.java:176)
at com.intellij.testFramework.UsefulTestCase.access$001(UsefulTestCase.java:81)
at com.intellij.testFramework.UsefulTestCase$2.run(UsefulTestCase.java:327)
at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait$2.invoke(EdtTestUtil.kt:30)
at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait$2.invoke(EdtTestUtil.kt:24)
at com.intellij.testFramework.EdtTestUtilKt.runInEdtAndWait(EdtTestUtil.kt:42)
at com.intellij.testFramework.EdtTestUtil$Companion.runInEdtAndWait(EdtTestUtil.kt:30)
at com.intellij.testFramework.EdtTestUtil.runInEdtAndWait(EdtTestUtil.kt)
at com.intellij.testFramework.UsefulTestCase.invokeTestRunnable(UsefulTestCase.java:359)
at com.intellij.testFramework.UsefulTestCase.runTest(UsefulTestCase.java:343)
at com.intellij.testFramework.UsefulTestCase.defaultRunBare(UsefulTestCase.java:370)
at com.intellij.testFramework.UsefulTestCase$3.run(UsefulTestCase.java:427)
at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait$1.invoke(EdtTestUtil.kt:26)
at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait$1.invoke(EdtTestUtil.kt:24)
at com.intellij.testFramework.EdtTestUtilKt$sam$Runnable$a15fd9f8.run(EdtTestUtil.kt)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:301)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:366)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

6 comments
Comment actions Permalink

Hi Matthias,

what intention do you test? Looks like it's SetupJDKFix and it is not test-ready as it tries to show the UI and our fixtures expect no UI at all. If you would suppress illegal access exception, you'll get NPE later and many other ugly exceptions.

BTW The UI test framework would be published shortly.

Anna

0
Comment actions Permalink

Hi Anna,

thanks for your fast response. Acutally I am not testing some UI but only a quickfix. Whenever I execute 

myFixture.launchAction

the code breaks [1]. Actually I thought the test runs headless. Do I really need a UI to test the quickfix change for the warning?

Thanks again,

Matthias

 

[1]

public class EJBInjectOnConcreteClassTest extends LightCodeInsightFixtureTestCase {
//LightPlatformCodeInsightFixtureTestCase (I get the same effect here)

@Override
protected String getTestDataPath() {
return ...
}

@SuppressWarnings("unchecked")
public void testBla() throws Exception {
myFixture.configureByFile("...");

List<IntentionAction> quickFixes = myFixture.getAllQuickFixes();
for (IntentionAction intention : quickFixes) {
myFixture.launchAction(intention);
}
}
}
0
Comment actions Permalink

you need to setup jdk in tests as now you obviously doesn't have one (SetupJdkFix).

BTW If I were you, I won't test all fixes which are available (and which would change code/model/whatever) but would find mine fix (by name) and start only it. So I suggest to filter 

quickFixes

and start only one per test.

0
Comment actions Permalink

Hi Anna,

well this is exactly the thing I don't understand. If I look at tests in the groovy plugin (i.e. https://github.com/joewalnes/idea-community/blob/master/plugins/groovy/test/org/jetbrains/plugins/groovy/dsl/GroovyDslTest.groovy) I can nowhere find an explicitly set SDK. 

From normal test frameworks I'd have guessed that, as a default value, IntelliJ just uses the SDK provided from the JVM running the test. This is wrong, obviously. But why does the Groovy test work and mine does not?

As far as I can see I could override getProjectDescriptor and provide some SDK in getSdk. However, this still feels wrong when not understanding why nobody else has this problem. There must be some different solution.

Thanks again,

Matthias

0
Comment actions Permalink

One more thing ... if I set the JDK explicitly using the project descriptor, IntelliJ will still call the SetupJdkFix, which in turn opens up the dialog. In effect, I get the same behavior.

The reason for this is that

com.intellij.openapi.roots.ui.configuration.IdeaProjectSettingsService#chooseAndSetSdk

will still open up the dialog (which cannot be opened as there is no frame). There is no check for a JDK here.

Matthias

Edit: By default LightCodeInsightFixtureTestCase uses a descriptor for JAVA_LATEST - so there's no need to set it myself. Still it does not work.

Edit 2: Your guess with filtering the quickfixes was a good one - filtering the SetupJDKFix makes it work. Still I don't know why the SetupJDKFix is available in this test case. It only checks for java.lang.Object to be available. As I've got a JDK configured this has to be true. Even more interesting, the isAvailable method of the fix is not even called (at least not in the debugger)

0
Comment actions Permalink

Never mind, I now use 

return JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();

which seems to work quite great :-)

1

Please sign in to leave a comment.