Thursday, 24 April 2025

Compatiblity between Kotlin and Java regarding Default Methods

In short, default methods in interfaces in Kotlin are not compatible with Java.

That's the short version.

The long version follows.

Let's have a simple Person interface written in Kotlin:

Now we wish to use it in Java.

This doesn't work. Although the interface defines a default implementation of getGender(), this default implementation is invisible when called from Java.

java: org.mrbear.kotlin.interfaces.MrBear is not abstract and does not override abstract method getGender() in org.mrbear.kotlin.interfaces.Person

Now, in the past there used to be something called @JvmDefault, but that is deprecated and doesn't work.

Instead it has been superseded by @JvmDefaultWithoutCompatibility1 and @JvmDefaultWithCompatibility2 (which, quite frankly, makes it a tad less understandable).

Also, when you use either annotation, you are required to add a command line parameter when you compile, or it won't work.

With compatibility requires -jvm-default=enable.

Without compatibility requires -jvm-default=no-compatibility.

However, it seems that the default is with compatibility that it is turned on automatically in Kotlin 2.2. Which will be released soonish hopefully.

How it works

Apparently what happens is that Kotlin automatically creates an Abstract class in the Interface that implements the methods that are default (under water). The abstract class is called Interface$DefaultImpls.

If you run Without Compatibility, it means that the DefaultImpls won't be generated but only "real Java default methods in the Interface". This means your interface in Kotlin will actually change (and is therefore not backwards compatible).

See reference [3] for more details.

References

[1] Kotlin LangRef - JvmDefaultWithoutCompatibility
https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.jvm/-jvm-default-without-compatibility/
[2] Kotlin LangRef - JvmDefaultWithCompatibility
https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.jvm/-jvm-default-with-compatibility/
[3] KT-4779 Generate default methods for implementations in interfaces
https://youtrack.jetbrains.com/issue/KT-4779/Generate-default-methods-for-implementations-in-interfaces

Thursday, 17 April 2025

How to install Javascript Engine in GraalVM - FollowUp

Things have changed compared to [3].

The GraalVM Updater was removed in GraalVM for JDK 21.[1] See issue 6855 [2].

Now we have to add Javascript using simple Maven dependencies that we add. See [4].

Also GraalVM seems to not like the Java standard scriptengine API, and support for it might go away soon.

References

[1] GraalVM Updater
https://www.graalvm.org/latest/reference-manual/graalvm-updater/
[2] [GR-46219] Remove the GraalVM Updater
https://github.com/oracle/graal/issues/6855
[3] How to install Javascript Engine in GraalVM
https://randomthoughtsonjavaprogramming.blogspot.com/2023/06/how-to-install-javascript-engine-in.html
[4] GraalVM - GraalJS
https://www.graalvm.org/latest/reference-manual/js/