JetBrains / intellij-platform-gradle-plugin

Gradle plugin for building plugins for IntelliJ-based IDEs
https://plugins.jetbrains.com/docs/intellij/gradle-prerequisites.html
Apache License 2.0
1.42k stars 270 forks source link

IntelliJ 'Run' cannot execute tests (IllegalAccessError: com.intellij.testFramework.UITestUtil); running via Gradle world #1757

Open sewe opened 1 week ago

sewe commented 1 week ago

What happened?

I have a build using org.jetbrains.intellij.platform (using the latest version: 2.0.1) with some tests using the IdeaTestFixtureFactory.

On the command-line using ./gradlew, these work fine.

They fail, however, when launching them using Run in IntelliJ (2024.2.1 Ultimate) with an

java.lang.IllegalAccessError: class com.intellij.testFramework.UITestUtil (in unnamed module @0x146ba0ac) cannot access class sun.awt.AWTAutoShutdown (in module java.desktop) because module java.desktop does not export sun.awt to unnamed module @0x146ba0ac

While I can, of course, configure the respective VM options manually, this is cumbersome, especially when frequently switching between tests and letting IntelliJ create the launch configurations on the fly.

Relevant log output or stack trace

java.lang.IllegalAccessError: class com.intellij.testFramework.UITestUtil (in unnamed module @0x146ba0ac) cannot access class sun.awt.AWTAutoShutdown (in module java.desktop) because module java.desktop does not export sun.awt to unnamed module @0x146ba0ac

    at com.intellij.testFramework.UITestUtil.replaceIdeEventQueueSafely(UITestUtil.java:73)
    at com.intellij.testFramework.UITestUtil.setupEventQueue(UITestUtil.java:60)
    at com.intellij.testFramework.common.TestApplicationKt.loadApp(testApplication.kt:107)
    at com.intellij.testFramework.common.TestApplicationKt.loadApp(testApplication.kt:95)
    at com.intellij.testFramework.common.TestApplicationKt.doInitTestApplication(testApplication.kt:86)
    at com.intellij.testFramework.common.TestApplicationKt.initTestApplication(testApplication.kt:76)
    at com.intellij.testFramework.TestApplicationManager$Companion.getInstance(TestApplicationManager.kt:59)
    at com.intellij.testFramework.TestApplicationManager.getInstance(TestApplicationManager.kt)
    at com.intellij.testFramework.fixtures.impl.BareTestFixtureImpl.setUp(BareTestFixtureImpl.java:17)
    at com.teamscale.ide.intellij.testing.BareTestFixtureTestBase.setUp(BareTestFixtureTestBase.java:22)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Steps to reproduce

My tests specify an explicit JBR:

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
        vendor = JvmVendorSpec.JETBRAINS
    }
}

and this is indeed picked up when IntelliJ creates the launch configuration:

/home/sewe/.gradle/jdks/jetbrains_s_r_o_-17-amd64-linux.2/bin/java -ea -Didea.test.cyclic.buffer.size=1048576 -javaagent:/home/sewe/.local/share/JetBrains/Toolbox/apps/intellij-idea-ultimate/lib/idea_rt.jar=38771:/home/sewe/.local/share/JetBrains/Toolbox/apps/intellij-idea-ultimate/bin -Dfile.encoding=UTF-8 @/tmp/idea_arg_file839703118 com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit5 com.teamscale.ide.intellij.servers.JnaSmokeTest,testIntelliJExposesJnaLibrary

Gradle IntelliJ Plugin version

2.0.1

Gradle version

8.9

Operating System

Linux

Link to build, i.e. failing GitHub Action job

No response

hsz commented 1 week ago

When running tests via Gradle, the IntelliJ Platform Gradle Plugin sets several flags and extra classpath entries to prepare the IntelliJ Platform for proper execution. Running tests with the IDEA runner isn't recommended because those flags differ between IntelliJ Platform versions and are dynamically read from the product-info.json file from the relevant distribution.

hsz commented 1 week ago

Please check if you have IDE configured to run tests using Gradle instead of IntelliJ IDEA:

image
sewe commented 1 week ago

Thanks, @hsz. Configuring Run tests using: Gradle works.

Alas, in my case this is somewhat inconvenient, as the IntelliJ plug-in is just one module in a larger project, for which Run tests using: IntelliJ IDEA is typically the better choice (faster, no confusing Run Task for ... popup with far too many choices).

Of course, I can use Choose per test and educate my colleagues about this, but this is not ideal. I assume Run tests using is not a setting I can change on a per-module basis, right?

At any rate, I was somehow hoping that IntelliJ would glean the necessary VM options from the Gradle build model and create an equivalent launch config from that, but I do understand that this is far trickier for a Gradle than a Maven build. (For my Eclipse plug-ins, m2e manages to extract the necessary information from Maven/Tycho to create an equivalent JUnit launch config quite reliably.)