Kotlin SAM Runtime Error: NoSuchMethodError: No static method - kotlin

Today I ran into a really strange runtime error while developing kotlin / android that involves SAM conversions and sub classing.
Here's a minimal example of pure java + kotlin. Here are two java classes:
public class A {
public interface I {
public void f();
}
public I i;
}
public class B extends A {}
And here is a kotlin main function:
fun main(args: Array<String>) {
A().i = B.I {}
}
This code compiles fine but at run time I get the following error:
Exception in thread "main" java.lang.NoSuchMethodError: B.I(Lkotlin/jvm/functions/Function0;)LA$I;
at MainKt.main(Main.kt:2)
Now, this is already bad -- if code like this does not work (it never will I guess) the compiler should raise an error. But at least one could say that it is bad idea to reference to the interface I via the subclass B instead of the place of definition A (i.e., A.I).
It's less clear though, if this code is in a sub class of B where I can reference I directly using I:
class C: B {
constructor() {
this.i = I {}
}
}
So my questions would be:
Why is this behavior happening at all?
If it is happening, why is the compiler not raising an error already?
PS: In android the error message looks similar to this, which is even more confusing:
Caused by: java.lang.NoSuchMethodError: No static method OnFocusChangeListener(Lkotlin/jvm/functions/Function2;)Landroid/view/View$OnFocusChangeListener; in class Landroid/widget/LinearLayout; or its super classes (declaration of 'android.widget.LinearLayout' appears in /system/framework/framework.jar:classes2.dex)

Define main method as static like-
companion object {
#JvmStatic fun main(args: Array<String>) {
A().i = B.I {}
}
}

Related

How can I run Nested Test in kotest?

I'm trying to migrate test framework from JUnit 5 to kotest.
I selected Annotation Spec at first (to check compatibility), but Nested Annotation doesn't work as expected
Sample code is below
class Outside : AnnotationSpec() {
#Test
fun runOutside() { }
#Nested
inner class Inside() {
#Test
fun runInside() { }
}
}
runOutside runs well, but runInside doesn't. The error message is java.lang.IllegalArgumentException: object is not an instance of declaring class
What's wrong ? is this a bug ?

Error: Main method not found despite I have declared a main function

I am new to kotlin and I am trying to use main function together with a class.
fun main() {
var demo = Person("Hello", 10)
println(demo)
}
private class Person (name: String, age: Int){
var name: String
var age: Int
init {
this.name = name
this.age = age
}
}
Although I have declared the main function, the compiler is still looking for the static main method in the class that I have defined, Person, and I got this error:
Error: Main method not found in class Person, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
What have I missed?
java Person is the problem, you are specifically telling it to look for the static void main method there. Top-level functions from Person.kt will be compiled into a PersonKt class by default and so you should run java PersonKt.
Also, the unnamed package you get by not specifying any package is weird in some ways, so I would recommend adding a package declaration from the start (and running java your.package.PersonKt).

Kotlin: How to resolve function name clashes when one interface defines a suspend function and the other does not

I had the following problem and was able to resolve the problem by renaming the functions. I am finding myself struggling doing that without my workaround...
How is the following implementation possible without modifying the interfaces:
interface A {
fun test() { }
}
interface B {
suspend fun test()
}
class C : A, B {
suspend fun test(){ // Change that line as you wish
// Implementation
}
Notes: I know of the Kotlin Wiki. But this is more difficult as IntelliJ didn't show that C is a valid implementation of A.
(My problem as far as I know is that one of the interface defines a suspend function and the other does not. My gut feeling is that a non-suspending function should be ok with being implemented as a suspending function, but there does not seem to be such a relation)
Thanks for helping out!

How to force immediate instantiation of enum values?

How to force immediate instantiation of enum values?
By default, in Kotlin enums are instantiated on first access (like objects/singletons), i.e., the following minimal example
class Foo
fun create(msg: String) = Foo().also { println("$msg") }
enum class A(val foo: Foo) {
ONE(create("1")),
TWO(create("2"))
}
enum class B(val foo: Foo) {
THREE(create("3")),
FOUR(create("4"))
}
fun main() {
println("main")
println(A.ONE)
}
outputs:
main
1
2
ONE
Is it possible to force the enums to be instantiated directly/statically before main, such that the output is as follows?
1
2
3
4
main
ONE
Sure, I could just put something like val ignore = listOf(A.ONE, B.THREE) somewhere, but I'd like to avoid such manual repetition.
Maybe there's a way using some existing annotation, or creating a new one, or something else? :)
JVM loads classes only on first access. This is not only for kotlin but also for Java. For Java we have ways to initialize a class before main, for instance, static initializer block, or Class.forName. Similarly you can use the static initializer block in Kotlin.
object Temp {
init {
A.ONE
}
#JvmStatic fun main(args: Array<String>) {
println("main")
println(A.ONE)
}
}

Kotlin compiler issue with overriding of Java final function in Kotlin

I’m dealing with following issue with Kotlin/Java Compiler.
Imagine following scenario: let First be a Java class with a final function and Second be a Kotlin class extending First with a function of the same name like the final function in First class, example:
// Java class
class First {
final void foo() { }
}
// Kotlin class
class Second: First() {
fun foo() { }
}
Obviously, it’s wrong because the final function foo() can not be overridden. However, compilation pass successfully and in run-time I get java.lang.LinkageError: Method void Second.foo() overrides final method in class First.
Is this correct behavior of compiler? I supposed that there will be some validations for this case. Thank you!