Kotlin Help

What's new in Kotlin 2.3.20-RC2

Released: March 3, 2026

The Kotlin 2.3.20-RC2 release is out! Here are some details of this EAP release:

IDE support

The Kotlin plugins that support 2.3.20-RC2 are bundled in the latest versions of IntelliJ IDEA and Android Studio. You don't need to update the Kotlin plugin in your IDE. All you need to do is change the Kotlin version to 2.3.20-RC2 in your build scripts.

See Update to a new release for details.

Kotlin compiler plugins

Kotlin 2.3.20-RC2 brings important updates to the Lombok and kotlin.plugin.jpa compiler plugins.

Lombok is now Alpha

Kotlin 1.5.20 introduced the experimental Lombok compiler plugin, which lets you generate and use Java's Lombok declarations in modules that mix Kotlin and Java code.

In 2.3.20-RC2, the Lombok compiler plugin is promoted to Alpha because we plan to productize this functionality, but it's still under development.

Improved JPA support in the kotlin.plugin.jpa plugin

The kotlin.plugin.jpa plugin now automatically applies the all-open compiler plugin with the newly added built-in JPA preset, in addition to the existing no-arg support.

Previously, using kotlin("plugin.jpa") enabled only the no-arg plugin with JPA presets. And when working with JPA entities, you had to explicitly apply and configure the all-open plugin to make JPA entity classes open.

Starting with Kotlin 2.3.20-RC2:

  • The all-open compiler plugin provides a JPA preset.

  • The Gradle org.jetbrains.kotlin.plugin.jpa plugin automatically applies the org.jetbrains.kotlin.plugin.all-open plugin with the JPA preset enabled.

  • The Maven JPA setup enables all-open with the JPA preset by default.

  • The Maven dependency org.jetbrains.kotlin:kotlin-maven-noarg now implicitly includes org.jetbrains.kotlin:kotlin-maven-allopen, so you no longer need to add it explicitly in the <plugin><dependencies> block.

As a result, JPA entities annotated with the following annotations are automatically treated as open and receive no-argument constructors without additional configuration:

  • javax.persistence.Entity

  • javax.persistence.Embeddable

  • javax.persistence.MappedSuperclass

  • jakarta.persistence.Entity

  • jakarta.persistence.Embeddable

  • jakarta.persistence.MappedSuperclass

This change simplifies build configuration and improves the out-of-the-box experience when using Kotlin with JPA frameworks.

Kotlin/Native: New interoperability mode for C or Objective-C libraries

If you use C or Objective-C libraries in your Kotlin Multiplatform libraries or applications, we invite you to test the new interoperability mode and share the results.

In general, Kotlin/Native enables importing C and Objective-C libraries into Kotlin. However, for Kotlin Multiplatform libraries, this functionality is currently affected by the KMP compatibility issues with older compiler versions.

In other words, if you publish a Kotlin Multiplatform library compiled with one Kotlin version, importing C or Objective-C libraries might make it impossible to use that Kotlin library in projects with an earlier Kotlin version.

To address this and other issues, the Kotlin team has been revising the interoperability mechanism used under the hood. Starting with Kotlin 2.3.20-Beta1, you can try the new mode through a compiler option.

How to try

  1. In your Gradle build file, check whether you have a cinterops {} block or a pod() dependency. If these are present, your project uses C or Objective-C libraries.

  2. Ensure your project uses 2.3.20-Beta1 or a later version.

  3. In the same build file, add the -Xccall-mode compiler option to the cinterop tool invocation:

    kotlin { targets.withType<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget>().configureEach { compilations.configureEach { cinterops.configureEach { extraOpts += listOf("-Xccall-mode", "direct") } } } }
  4. Build and test your project as usual by running unit tests, the app, and so on.

    You can also use the --continue option to allow Gradle to continue executing tasks even after failures, helping to find more problems at once.

Report your results

The new interoperability mode is supposed to be a drop-in replacement in most cases. We're planning to eventually enable it by default. But to achieve that, we need to ensure it works as well as possible and test it on a wide range of projects, because:

  • Some C and Objective-C declarations aren't supported yet in the new mode (mostly because they conflict with the compatibility issues). We'd like to better understand the real-world impact of this and prioritize future steps accordingly.

  • There may be bugs or things we didn't consider. Testing languages with numerous interacting features is challenging, and testing the interaction between languages (each with a unique set of features) is even more so.

Help us examine real-world projects and identify challenging cases. Whether you encounter any issues or not, share your results in the comments to this YouTrack issue.

Gradle

Kotlin 2.3.20-RC2 is compatible with new versions of Gradle and includes changes to Kotlin/JVM compilation in the Kotlin Gradle plugin.

Compatibility with Gradle 9.3.0

Kotlin 2.3.20-RC2 is fully compatible with Gradle 7.6.3 through 9.3.0. You can also use Gradle versions up to the latest Gradle release. However, be aware that doing so may result in deprecation warnings, and some new Gradle features might not work.

Kotlin/JVM compilation uses Build tools API by default

In Kotlin 2.3.20-RC2, Kotlin/JVM compilation in the Kotlin Gradle plugin uses the Build tools API (BTA) by default. This change in the internal compilation infrastructure enables faster development of build tool support for the Kotlin compiler.

If you notice any issues, share your feedback in our issue tracker.

Maven: Simplified setup for Kotlin projects

Kotlin 2.3.20-RC2 makes it easier to set up Kotlin in Maven projects. Now Kotlin supports automatic configuration of source roots and Kotlin's standard library.

With the new configuration, when you create a new Kotlin project with the Maven build system or introduce Kotlin to your existing Java Maven project, you don't need to manually create source roots or add the kotlin-stdlib dependency in your POM build file.

How to enable

In your pom.xml file, add <extensions>true</extensions> to the <build><plugins> section of the Kotlin Maven plugin:

<build> <plugins> <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>2.3.20-RC2</version> <extensions>true</extensions> <!-- Add this extension --> </plugin> </plugins> </build>

The new extension automatically:

  • Creates src/main/kotlin and src/test/kotlin directories without changing existing Kotlin or Java source roots.

  • Adds the kotlin-stdlib dependency unless it's already defined.

You can also opt out of the automatic addition of Kotlin's standard library. For that, add the following to the <properties> section:

<project> <properties> <!-- Disable smart defaults via property --> <kotlin.smart.defaults.enabled>false</kotlin.smart.defaults.enabled> </properties> </project>

For more information on Maven configuration in Kotlin projects, see Configure a Maven project.

Standard library: New API for creating immutable copies of Map.Entry

Kotlin 2.3.20-RC2 introduces the Map.Entry.copy() extension function for creating an immutable copy of a Map.Entry. This function allows you to reuse entries obtained from Map.entries after modifying the map by copying them first.

Map.Entry.copy() is Experimental. To opt in, use the @OptIn(ExperimentalStdlibApi::class) annotation or the compiler option -opt-in=kotlin.ExperimentalStdlibApi.

Here's an example of using Map.Entry.copy() to remove entries from a mutable map:

@OptIn(ExperimentalStdlibApi::class) fun main() { val map = mutableMapOf(1 to 1, 2 to 2, 3 to 3, 4 to 4) val toRemove = map.entries .filter { it.key % 2 == 0 } .map { it.copy() } map.entries.removeAll(toRemove) println("map = $map") // map = {1=1, 3=3} }
19 February 2026