ClassCastException during runIde but not during tests

Answered

Given this example library code:

interface Foo<in A, out B> : (A) -> B {
override fun invoke(p1: A): B
}

object FooImpl : Foo<Unit, Unit> {
override fun invoke(p1: Unit) = Unit
}

When my plugin runs this cast:

FooImpl as (Unit) -> Unit

This exception is thrown if the cast occurs in plugin code:

```

java.lang.ClassCastException: com.commonwealthrobotics.bowlerintellij.module.FooImpl cannot be cast to kotlin.jvm.functions.Function1
at com.commonwealthrobotics.bowlerintellij.module.BowlerScriptRunProfileState.execute(BowlerScriptRunProfileState.kt:17)
at com.intellij.execution.runners.DefaultRunProgramRunner$execute$1.invoke(DefaultRunProgramRunner.kt:29)
at com.intellij.execution.runners.DefaultRunProgramRunner$execute$1.invoke(DefaultRunProgramRunner.kt:12)
at com.intellij.execution.impl.ExecutionManagerImpl$startRunProfile$1.invoke(ExecutionManagerImpl.kt:147)
at com.intellij.execution.impl.ExecutionManagerImpl$startRunProfile$1.invoke(ExecutionManagerImpl.kt:60)
at com.intellij.execution.impl.ExecutionManagerImpl$doStartRunProfile$startRunnable$1.run(ExecutionManagerImpl.kt:208)
at com.intellij.openapi.application.TransactionGuardImpl$2.run(TransactionGuardImpl.java:201)
at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:802)
at com.intellij.openapi.application.impl.ApplicationImpl.lambda$invokeLater$4(ApplicationImpl.java:322)
at com.intellij.openapi.application.impl.FlushQueue.doRun(FlushQueue.java:84)
at com.intellij.openapi.application.impl.FlushQueue.runNextEvent(FlushQueue.java:132)
at com.intellij.openapi.application.impl.FlushQueue.flushNow(FlushQueue.java:47)
at com.intellij.openapi.application.impl.FlushQueue$FlushNow.run(FlushQueue.java:188)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:776)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:746)
at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:967)
at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:839)
at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$8(IdeEventQueue.java:450)
at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:744)
at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$9(IdeEventQueue.java:449)
at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:802)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:497)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

```

No exception is thrown when the cast is run from a test. In both cases, IntelliJ shows that the cast is useless.

 

Why does this cast throw an exception when run from my plugin code but not when run in a test?

 

I am using Kotlin 1.4.10, targeting JVM bytecode version 8, Zulu JDK 11, targeting IntelliJ versions since 193, and IntelliJ version:

IntelliJ IDEA 2020.2.3 (Ultimate Edition)
Build #IU-202.7660.26, built on October 6, 2020
Licensed to Bowler / Ryan Benasutti
Subscription is active until October 13, 2021
For non-commercial open source development only.
Runtime version: 11.0.8+10-b944.34 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Linux 5.8.18-200.fc32.x86_64
GC: ParNew, ConcurrentMarkSweep
Memory: 3987M
Cores: 16
Non-Bundled Plugins: VisualVMLauncher, intellij.haskell, org.ice1000.julia, org.antlr.intellij.plugin, org.toml.lang, org.jetbrains.kotlin, kotlintest-plugin-intellij, no.tornado.tornadofx.idea, Pythonid, idea.plugin.protoeditor
Current Desktop: GNOME

6 comments
Comment actions Permalink

Yes, Gradle shows that it is a part of the plugin's `runtimeClasspath` configuration.

0
Comment actions Permalink

Are they packaged in the resulting plugin distribution ZIP? Can you share your project sources?

0
Comment actions Permalink

I don't think a distribution zip is generated when I run the runIde task. Within build/idea-sandbox/plugins/plugin/lib I see these relevant files:

kotlin-stdlib-1.4.10.jar
kotlin-stdlib-common-1.4.10.jar
kotlin-stdlib-jdk7-1.4.0.jar
kotlin-stdlib-jdk8-1.4.0.jar

 

Happy to share the sources. The repo is here. The line producing the exception is here. You can reproduce the problem by running the runIde task, creating a Bowler run configuration, selecting a .groovy file as the Bowler script, and running that run configuration. The stacktrace will be printed to the console.

0
Comment actions Permalink

Thanks, it looks like https://youtrack.jetbrains.com/issue/IDEA-253683. Does it work correctly when running the plugin in 2020.3?

0
Comment actions Permalink

Yes, it works correctly using 2020.3 EAP.

0

Please sign in to leave a comment.