在从源代码构建的 IntelliJ 社区上尝试 运行 no-op `LightCodeInsightFixtureTestCase` 时出现 `NullPointerException`

`NullPointerException` when trying to run no-op `LightCodeInsightFixtureTestCase` on IntelliJ Community built from source

我尝试创建一个简单的 IDEA 插件和一个基于 this 手册的测试用例:

package com.example;

import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;

public class NoopTest extends LightCodeInsightFixtureTestCase {
    public void testNothing() {

    }
}

然后我创建 JUnit 运行 配置,使其成为 运行 这个 class,将工作目录指向 D:\idea-community\bin 目录(见下文)并根据手册:

-ea -Xbootclasspath/p:../out/classes/production/boot -XX:+HeapDumpOnOutOfMemoryError -Xmx512m -XX:MaxPermSize=320m -Didea.system.path=../test-system -Didea.home.path=../ -Didea.config.path=../test-config -Didea.test.group=ALL_EXCLUDE_DEFINED

然后我运行在调试模式下测试并得到以下错误:

CompositeException (2 nested):
------------------------------
[0]: java.lang.NullPointerException
    at com.intellij.testFramework.IdeaTestUtil.createMockJdk(IdeaTestUtil.java:77)
    at com.intellij.testFramework.IdeaTestUtil.getMockJdk(IdeaTestUtil.java:72)
    at com.intellij.testFramework.IdeaTestUtil.getMockJdk17(IdeaTestUtil.java:85)
    at com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase.getSdk(LightCodeInsightFixtureTestCase.java:60)
    at com.intellij.testFramework.LightProjectDescriptor.lambda$createContentEntry(LightProjectDescriptor.java:135)
    at com.intellij.openapi.roots.ModuleRootModificationUtil.updateModel(ModuleRootModificationUtil.java:143)
    at com.intellij.testFramework.LightProjectDescriptor.createContentEntry(LightProjectDescriptor.java:134)
    at com.intellij.testFramework.LightProjectDescriptor.lambda$setUpProject[=13=](LightProjectDescriptor.java:58)
    at com.intellij.openapi.application.WriteAction.run(WriteAction.java:105)
    at com.intellij.testFramework.LightProjectDescriptor.setUpProject(LightProjectDescriptor.java:52)
    at com.intellij.testFramework.LightPlatformTestCase.initProject(LightPlatformTestCase.java:242)
    at com.intellij.testFramework.LightPlatformTestCase.doSetup(LightPlatformTestCase.java:303)
    at com.intellij.testFramework.fixtures.impl.LightIdeaTestFixtureImpl.setUp(LightIdeaTestFixtureImpl.java:37)
    at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.lambda$setUp(CodeInsightTestFixtureImpl.java:1190)
    at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait.invoke(EdtTestUtil.kt:19)
    at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait.invoke(EdtTestUtil.kt:14)
    at com.intellij.testFramework.EdtTestUtilKt.runInEdtAndWait(EdtTestUtil.kt:55)
    at com.intellij.testFramework.EdtTestUtil$Companion.runInEdtAndWait(EdtTestUtil.kt:19)
    at com.intellij.testFramework.EdtTestUtil.runInEdtAndWait(EdtTestUtil.kt)
    at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.setUp(CodeInsightTestFixtureImpl.java:1189)
    at com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase.setUp(LightCodeInsightFixtureTestCase.java:76)
    at com.intellij.testFramework.UsefulTestCase.defaultRunBare(UsefulTestCase.java:358)
    at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait.invoke(EdtTestUtil.kt:19)
    at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait.invoke(EdtTestUtil.kt:14)
    at com.intellij.testFramework.EdtTestUtilKt$runInEdtAndWait.run(EdtTestUtil.kt:59)
    at java.awt.event.InvocationEvent.dispatch$$$capture(InvocationEvent.java:301)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access0(EventQueue.java:97)
    at java.awt.EventQueue.run(EventQueue.java:709)
    at java.awt.EventQueue.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:361)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
    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)

[1]: java.lang.AssertionError: setUp() has not been called
    at org.junit.Assert.fail(Assert.java:88)
    at org.junit.Assert.assertTrue(Assert.java:41)
    at com.intellij.testFramework.fixtures.impl.BaseFixture.tearDown(BaseFixture.java:48)
    at com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl.tearDown(LightTempDirTestFixtureImpl.java:64)
    at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.lambda$null(CodeInsightTestFixtureImpl.java:1241)
    at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait.invoke(EdtTestUtil.kt:19)
    at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait.invoke(EdtTestUtil.kt:14)
    at com.intellij.testFramework.EdtTestUtilKt.runInEdtAndWait(EdtTestUtil.kt:37)
    at com.intellij.testFramework.EdtTestUtil$Companion.runInEdtAndWait(EdtTestUtil.kt:19)
    at com.intellij.testFramework.EdtTestUtil.runInEdtAndWait(EdtTestUtil.kt)
    at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.lambda$tearDown(CodeInsightTestFixtureImpl.java:1241)
    at com.intellij.testFramework.RunAll.collectExceptions(RunAll.java:60)
    at com.intellij.testFramework.RunAll.run(RunAll.java:52)
    at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.tearDown(CodeInsightTestFixtureImpl.java:1247)
    at com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase.tearDown(LightCodeInsightFixtureTestCase.java:88)
    at com.intellij.testFramework.UsefulTestCase.defaultRunBare(UsefulTestCase.java:370)
    at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait.invoke(EdtTestUtil.kt:19)
    at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait.invoke(EdtTestUtil.kt:14)
    at com.intellij.testFramework.EdtTestUtilKt$runInEdtAndWait.run(EdtTestUtil.kt:59)
    at java.awt.event.InvocationEvent.dispatch$$$capture(InvocationEvent.java:301)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access0(EventQueue.java:97)
    at java.awt.EventQueue.run(EventQueue.java:709)
    at java.awt.EventQueue.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:361)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
    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)

我的设置:

  1. IDEA社区,按照“Check Out And Build Community Edition”手册点击"Build - Build project"在本地建立。源根目录的路径类似于 D:\idea-community\,因此有 D:\idea-community\getPlugins.bat。 Git 提交是 ef98a0ccb.
  2. IDEA 在调试模式下成功 运行s。
  3. 这个 IDEA 作为 IntelliJ 平台插件 SDK 添加到我的插件项目中。
  4. 我从我的插件项目中成功 运行 IDEA,甚至浏览了源代码。

如何在 运行 测试并通过测试时修复错误?

我能够通过删除 D:\idea-community\out\production\intellij.pycharm.community\META-INF\PyCharmCorePlugin.xml 来解决问题,但这感觉像是作弊,因为每次构建都会重新创建该文件。

经过进一步调查,我发现 PlatformTestCase.doAutodetectPlatformPrefix() 检测到 PyCharmCore 而不是 Idea 并且看起来模拟 Java SDK(或其他)未加载到其中案例,因此 NullPointerException.

我在 JetBrains 论坛上发现了一些类似问题的提及 here (from 2009), here (from 2012) and there (from 2014). It looks like platform autodetection in tests is a recent thing(自 2015 年起)。此外,它似乎覆盖了我作为 JVM 选项传递的任何 -Didea.platform.prefix=Idea,因此我看不到任何更好的解决方案。