working on trying to isolate it down now
# kotlintest
b
working on trying to isolate it down now
@sam still trimming it down, but looks like it isn't related to the inner class, it's related to create an anonymous class which overrides a function from a parent? my kotlintest version may be a bit old, i'll try with latest as well
s
Try 3.3.3
b
ok, still see it in 3.3.3
ok, think i've got it simplified
the class under test is
Copy code
abstract class Foo<T, U>(
    val lambda: (T) -> Boolean
) {
    abstract fun fun1(key: T, value: U)
}
and the test is
Copy code
class FooTest : ShouldSpec() {
    override fun isolationMode(): IsolationMode? = IsolationMode.InstancePerLeaf

    private val keyChanges = mutableListOf<Pair<Int, String?>>()

    private val map: Int = 1.apply {
        object : Foo<Int, String>({ it == 1}) {
            override fun fun1(key: Int, value: String) {
                keyChanges.add(key to value)
            }
        }
    }

    init {
    }
}
the output i get is
Copy code
WARNING: TestEngine with ID 'kotlintest' failed to discover tests
java.lang.VerifyError: Call to wrong <init> method
Exception Details:
  Location:
    org/jitsi/nlj/util/FooTest.<init>()V @49: invokespecial
  Reason:
    Type 'org/jitsi/nlj/util/FooTest$map$1$1' (constant pool 35) is not assignable to 'org/jitsi/nlj/util/FooTest$$special$$inlined$apply$lambda$1' (constant pool 48)
  Bytecode:
    0x0000000: 2a01 0401 b700 192a 3a04 bb00 1b59 b700
    0x0000010: 1dc0 001f 3a05 1904 1905 b500 212a 043c
    0x0000020: 3a04 1b3d 033e bb00 2359 b200 29c0 002b
    0x0000030: 2ab7 0030 5700 1b36 0519 0415 05b5 0032
    0x0000040: b1                                     

	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:264)
	at io.kotlintest.runner.jvm.TestDiscovery.loadClasses(TestDiscovery.kt:118)
	at io.kotlintest.runner.jvm.TestDiscovery.discover(TestDiscovery.kt:44)
	at io.kotlintest.runner.junit5.KotlinTestEngine.discover(KotlinTestEngine.kt:68)
	at io.kotlintest.runner.junit5.KotlinTestEngine.discover(KotlinTestEngine.kt:28)
	at org.junit.platform.launcher.core.DefaultLauncher.discoverEngineRoot(DefaultLauncher.java:177)
	at org.junit.platform.launcher.core.DefaultLauncher.discoverRoot(DefaultLauncher.java:164)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
and it seems like many different things can make the error go away, for example not calling
keyChanges.add(key to value)
will make it go away
removing the lambda ctor arg will also make the error go away
s
And you’re compiling and running with the same version of the jdk
b
yeah
my kotlin version is a little old (1.3.21), trying 1.3.40
s
I don’t think it’s a kotlin version iossue
b
yeah 1.3.40 is the same
do you see the same error?
s
I’m busy at work atm, so will have to check it later
b
👍
s
verify error is usually when the generated bytecode is not valid in another version of the jdk
so it could be a bug in kotlinc I suppose
I’d be surprised if KT was causing it, I think it’s more likely KT is just exposing it because you’re already nested inside the init block
b
hm i tried just calling
val x = Class.forName("org.jitsi.nlj.util.FooTest").kotlin
inside a scratch and that errors as well
which is confusing, because i can change code that exists only inside the kotlintest file and that fixes it
s
what about if you remove the .kotlin
b
still errors
s
what about if you put that line inside a fun main() {}
b
same
s
Something is just wrong in your setup then if you can’t even instantiate the Class for that class
assuming that class exists on your class path
b
i can run code which uses it and it runs fine
s
Copy code
fun main() { 
val x = Class.forName("org.jitsi.nlj.util.FooTest")
println(x)
}
errors ?
b
yeah
s
what’s the excepiton
b
Copy code
Exception in thread "main" java.lang.VerifyError: Call to wrong <init> method
Exception Details:
  Location:
    org/jitsi/nlj/util/FooTest.<init>()V @49: invokespecial
  Reason:
    Type 'org/jitsi/nlj/util/FooTest$map$1$1' (constant pool 35) is not assignable to 'org/jitsi/nlj/util/FooTest$$special$$inlined$apply$lambda$1' (constant pool 48)
  Bytecode:
    0x0000000: 2a01 0401 b700 192a 3a04 bb00 1b59 b700
    0x0000010: 1dc0 001f 3a05 1904 1905 b500 212a 043c
    0x0000020: 3a04 1b3d 033e bb00 2359 b200 29c0 002b
    0x0000030: 2ab7 0030 5700 1b36 0519 0415 05b5 0032
    0x0000040: b1                                     

	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:264)
	at org.jitsi.nlj.util.TempKt.main(Temp.kt:20)
	at org.jitsi.nlj.util.TempKt.main(Temp.kt)
s
Ok so some inlined function cannot be assigned to a variable
do you have something inlined in the test class
b
no
inline
if that's what you mean?
s
yeah
can you try removing things from the test class until the error goes away
b
yeah, two things above (one change was in the test) that i found fixes it, which is removing the line inside the overridden method
s
Ok leave it with me for later
b
cool, thanks
it looks like accessing any FooTest member variable inside that overridden method will still cause the error. e.g. this still fails:
Copy code
class FooTest : ShouldSpec() {
    override fun isolationMode(): IsolationMode? = IsolationMode.InstancePerLeaf

    private val num = 42

    private val map: Int = 1.apply {
        object : Foo<Int, String>({ it == 1}) {
            override fun fun1(key: Int, value: String) {
                println(num)
            }
        }
    }

    init {
    }
}
s
ok
w
Btw it’s 100% not related to KT, since it fails even for a regular JUnit test
If anything it could be junit platform bug (assuming not a Kotlin bug)
s
It’s more likely a kotlinc bug imo
w
s
Yeah looks similar
althouugh he’s not in a coroutine
b
found that one, but yeah didn't give much to go on
s
Like @wasyl said it's nothing to do with KT
I've reduced the failing case to
Copy code
fun main() {
  Class.forName("com.sksamuel.kotlintest.FooTest")
}

class FooTest {

  val num = 42

  private val map: Int = 1.apply {
    object : Foo({ it == 1 }) {
      override fun fun1() {
        println(num)
      }
    }
  }

  init {
  }
}

abstract class Foo(
  val lambda: (Any) -> Boolean
) {
  abstract fun fun1()
}
and it still errors in the compiler
This is the smallest use case I can find
Copy code
fun main() {
  Class.forName("a.b.c.X")
}

class X {
  val num = 42
  val map: Int = 1.apply {
    object : Y({ true }) {
      override fun fun1() {
        println(num)
      }
    }
  }
}

abstract class Y(val lambda: () -> Boolean) {
  abstract fun fun1()
}
b
cool, thanks @sam. i guess i'll file a bug and use that last example. will just disable the test for now i guess
Filed
b
thanks, will vote 👍
s
cool