From d9775f92351f871734771489c9e6e1dd2ac35787 Mon Sep 17 00:00:00 2001 From: MutwakilX <144057106+Wadamzmail@users.noreply.github.com> Date: Sat, 25 Jul 2026 17:42:09 +0200 Subject: [PATCH 1/2] fix: Remove isAtLeastJava9 check it useless on Android if we already embedded jrt-fs on the Application and breaks Kotlin LSP initialization on Android 10 and less devices so always use Application class loader --- ...ion-class-loader-to-find-jrt-file-sy.patch | 69 ++++++++++++++----- 1 file changed, 53 insertions(+), 16 deletions(-) diff --git a/patches/0001-fix-use-application-class-loader-to-find-jrt-file-sy.patch b/patches/0001-fix-use-application-class-loader-to-find-jrt-file-sy.patch index f0e458e..eec6d4d 100644 --- a/patches/0001-fix-use-application-class-loader-to-find-jrt-file-sy.patch +++ b/patches/0001-fix-use-application-class-loader-to-find-jrt-file-sy.patch @@ -1,6 +1,6 @@ -From 6f5f186a640e0d4ef0bff4d18dbb36f969dc5b16 Mon Sep 17 00:00:00 2001 -From: Akash Yadav -Date: Thu, 26 Mar 2026 14:12:33 +0530 +From 854499acfc4dc309d4ff80962eb7d7d909fac899 Mon Sep 17 00:00:00 2001 +From: Wadamzmail +Date: Sat, 25 Jul 2026 17:06:11 +0200 Subject: [PATCH 1/9] fix: use application class loader to find jrt:/ file system @@ -9,24 +9,61 @@ To ensure Kotlin's CoreJrtFileSystem can find the jrt:/ file system, we need to use the application class loader. This makes it possible for the consuming application to provide its own implementation of the jrt:/ file system (as we do in Code On the Go). -Signed-off-by: Akash Yadav --- - .../org/jetbrains/kotlin/cli/jvm/modules/CoreJrtFileSystem.kt | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + .../cli/jvm/modules/CoreJrtFileSystem.kt | 31 ++++++++----------- + 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/modules/CoreJrtFileSystem.kt b/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/modules/CoreJrtFileSystem.kt -index 335a4db84c47..c399ca5bca10 100644 +index 335a4db..e075e42 100644 --- a/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/modules/CoreJrtFileSystem.kt +++ b/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/modules/CoreJrtFileSystem.kt -@@ -83,7 +83,7 @@ class CoreJrtFileSystem : DeprecatedVirtualFileSystem() { - if (isAtLeastJava9()) { - // If the runtime JDK is set to 9+ it has JrtFileSystemProvider, - // but to load proper jrt-fs (one that is pointed by jdkHome) we should provide "java.home" path +@@ -23,7 +23,6 @@ import com.intellij.util.containers.ConcurrentFactoryMap + import com.intellij.util.io.URLUtil + import java.io.File + import java.net.URI +-import java.net.URLClassLoader + import java.nio.file.FileSystem + import java.nio.file.FileSystems + +@@ -73,24 +72,20 @@ class CoreJrtFileSystem : DeprecatedVirtualFileSystem() { + + private val globalJrtFsCache = ConcurrentFactoryMap.createMap { jdkHomePath -> + val jdkHome = File(jdkHomePath) +- val jrtFsJar = loadJrtFsJar(jdkHome) ?: return@createMap null ++ loadJrtFsJar(jdkHome) ?: return@createMap null + val rootUri = URI.create(StandardFileSystems.JRT_PROTOCOL + ":/") ++ + /* +- The ClassLoader, that was used to load JRT FS Provider actually lives as long as current thread due to ThreadLocal leak in jrt-fs, +- See https://bugs.openjdk.java.net/browse/JDK-8260621 +- So that cache allows us to avoid creating too many classloaders for same JDK and reduce severity of that leak +- */ +- if (isAtLeastJava9()) { +- // If the runtime JDK is set to 9+ it has JrtFileSystemProvider, +- // but to load proper jrt-fs (one that is pointed by jdkHome) we should provide "java.home" path - FileSystems.newFileSystem(rootUri, mapOf("java.home" to jdkHome.absolutePath)) -+ FileSystems.newFileSystem(rootUri, mapOf("java.home" to jdkHome.absolutePath), CoreJrtFileSystem::class.java.classLoader) - } else { - val classLoader = URLClassLoader(arrayOf(jrtFsJar.toURI().toURL()), null) - // If the runtime JDK is set to <9, there are no JrtFileSystemProvider, +- } else { +- val classLoader = URLClassLoader(arrayOf(jrtFsJar.toURI().toURL()), null) +- // If the runtime JDK is set to <9, there are no JrtFileSystemProvider, +- // we should create classloader with jrt-fs.jar, and DO NOT NEED to pass "java.home" path, +- // as otherwise it will incur additional classloader creation +- FileSystems.newFileSystem(rootUri, emptyMap(), classLoader) +- } ++ * CodeOnTheGo bundles its own jrt-fs implementation inside the APK. ++ * Therefore, we do not need to check the runtime Java version here. ++ * Always resolve the JRT FileSystemProvider from the application's ClassLoader, ++ * using the bundled implementation regardless of the Android or Java runtime. ++ */ ++ FileSystems.newFileSystem( ++ rootUri, ++ mapOf("java.home" to jdkHome.absolutePath), ++ CoreJrtFileSystem::class.java.classLoader ++ ) + } + } +-} ++} +\ No newline at end of file -- -2.54.0 +2.52.0 From 826c6382a77e0f80dfd5663957391b93cd6e9d35 Mon Sep 17 00:00:00 2001 From: MutwakilX <144057106+Wadamzmail@users.noreply.github.com> Date: Sun, 26 Jul 2026 13:59:55 +0200 Subject: [PATCH 2/2] refactor: remove unused loadJrtFsJar call --- ...ation-class-loader-to-find-jrt-file-sy.patch | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/patches/0001-fix-use-application-class-loader-to-find-jrt-file-sy.patch b/patches/0001-fix-use-application-class-loader-to-find-jrt-file-sy.patch index eec6d4d..c194129 100644 --- a/patches/0001-fix-use-application-class-loader-to-find-jrt-file-sy.patch +++ b/patches/0001-fix-use-application-class-loader-to-find-jrt-file-sy.patch @@ -1,20 +1,20 @@ -From 854499acfc4dc309d4ff80962eb7d7d909fac899 Mon Sep 17 00:00:00 2001 -From: Wadamzmail +From a20de7ca03c18f2ff8eb79380181133d349c80ed Mon Sep 17 00:00:00 2001 +From: Akash Yadav Date: Sat, 25 Jul 2026 17:06:11 +0200 -Subject: [PATCH 1/9] fix: use application class loader to find jrt:/ file - system +Subject: [PATCH 1/9] fix: use application class loader to find jrt:/ file system The JRT file system is not available on Android. It needs to be part of the application. To ensure Kotlin's CoreJrtFileSystem can find the jrt:/ file system, we need to make it use the application class loader. This makes it possible for the consuming application to provide its own implementation of the jrt:/ file system (as we do in Code On the Go). +Co-authored-by: Wadamzmail --- - .../cli/jvm/modules/CoreJrtFileSystem.kt | 31 ++++++++----------- - 1 file changed, 13 insertions(+), 18 deletions(-) + .../cli/jvm/modules/CoreJrtFileSystem.kt | 30 ++++++++----------- + 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/modules/CoreJrtFileSystem.kt b/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/modules/CoreJrtFileSystem.kt -index 335a4db..e075e42 100644 +index 335a4db..3e07be2 100644 --- a/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/modules/CoreJrtFileSystem.kt +++ b/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/modules/CoreJrtFileSystem.kt @@ -23,7 +23,6 @@ import com.intellij.util.containers.ConcurrentFactoryMap @@ -25,12 +25,11 @@ index 335a4db..e075e42 100644 import java.nio.file.FileSystem import java.nio.file.FileSystems -@@ -73,24 +72,20 @@ class CoreJrtFileSystem : DeprecatedVirtualFileSystem() { +@@ -73,24 +72,19 @@ class CoreJrtFileSystem : DeprecatedVirtualFileSystem() { private val globalJrtFsCache = ConcurrentFactoryMap.createMap { jdkHomePath -> val jdkHome = File(jdkHomePath) - val jrtFsJar = loadJrtFsJar(jdkHome) ?: return@createMap null -+ loadJrtFsJar(jdkHome) ?: return@createMap null val rootUri = URI.create(StandardFileSystems.JRT_PROTOCOL + ":/") + /*