From fde8a046bcc28dee1b4b20c8908f99dd53c1dd5c Mon Sep 17 00:00:00 2001 From: Edbert Chan Date: Fri, 15 Aug 2025 14:11:13 -0700 Subject: [PATCH 1/4] Update kover.bzl Adding Kover to Xbootclasspath. If a function runs that uses the bootstrap classloader's search path, you will hit a ClassNotFoundException as the runtime tries to find Kover agents' classes. --- kotlin/internal/jvm/kover.bzl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kotlin/internal/jvm/kover.bzl b/kotlin/internal/jvm/kover.bzl index 9521ea926..472dbd4d4 100644 --- a/kotlin/internal/jvm/kover.bzl +++ b/kotlin/internal/jvm/kover.bzl @@ -78,8 +78,11 @@ def get_kover_jvm_flags(kover_agent_files, kover_args_file): returns: the flag string to be used by test runner jvm """ - - return "-javaagent:%s=file:%s" % (kover_agent_files[0].short_path, kover_args_file.short_path) + jvm_args = [ + "-Xbootclasspath/a:%s" % (kover_agent_files[0].short_path), + "-javaagent:%s=file:%s" % (kover_agent_files[0].short_path, kover_args_file.short_path) + ] + return " ".join(jvm_args) def create_kover_agent_actions(ctx, name): """ Generate the actions needed to emit Kover code coverage metadata file. It creates From 0a2ad854d15f88deae9f394fa441bc74b3f3ba5b Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 9 Sep 2025 14:23:12 -0700 Subject: [PATCH 2/4] Loosen release action tag pattern --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ef2be9802..31b10c1e7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,7 +5,7 @@ name: Release Binary Package on: push: tags: - - "v*.*.*" + - "v*" jobs: build: From 0556bd70a626315ea53e67b7641deebad1562827 Mon Sep 17 00:00:00 2001 From: Ben Lee Date: Thu, 10 Apr 2025 17:28:37 -0700 Subject: [PATCH 3/4] Kotlin 2.1.10+ prep (#1299) * Kotlin 2.1.10+ prep * More * Formatting --- .../kotlin/plugin/jdeps/k2/JdepsK2Utils.kt | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/k2/JdepsK2Utils.kt b/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/k2/JdepsK2Utils.kt index 3068fd97d..11a5cd1dd 100644 --- a/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/k2/JdepsK2Utils.kt +++ b/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/k2/JdepsK2Utils.kt @@ -1,14 +1,26 @@ package io.bazel.kotlin.plugin.jdeps.k2 import org.jetbrains.kotlin.descriptors.SourceElement -import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression -import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression -import org.jetbrains.kotlin.fir.java.JavaBinarySourceElement import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource +private object RefCache { + val jbseClass: Class<*>? by lazy { + runCatching { + Class.forName("org.jetbrains.kotlin.fir.java.JavaBinarySourceElement") + }.getOrNull() + } + + val jbseGetJavaClassMethod by lazy { + jbseClass + ?.runCatching { + getMethod("getJavaClass") + }?.getOrNull() + } +} + /** * Returns whether class is coming from JVM runtime env. There is no need to track these classes. * @@ -27,11 +39,16 @@ internal fun DeserializedContainerSource.classId(): ClassId? = } internal fun SourceElement.binaryClass(): String? = - when (this) { - is KotlinJvmBinarySourceElement -> binaryClass.location - is JvmPackagePartSource -> this.knownJvmBinaryClass?.location - is JavaBinarySourceElement -> this.javaClass.virtualFile.path - else -> null + if (this is KotlinJvmBinarySourceElement) { + binaryClass.location + } else if (this is JvmPackagePartSource) { + this.knownJvmBinaryClass?.location + } else if (RefCache.jbseClass != null && RefCache.jbseClass!!.isInstance(this)) { + val jClass = RefCache.jbseGetJavaClassMethod!!.invoke(this) + val virtualFile = jClass!!.javaClass.getMethod("getVirtualFile").invoke(jClass) + virtualFile.javaClass.getMethod("getPath").invoke(virtualFile) as? String + } else { + null } internal fun DeserializedContainerSource.binaryClass(): String? = From cdd809930f3cbe65fa4668a36f9bc96a3979dc62 Mon Sep 17 00:00:00 2001 From: Ben Lee Date: Fri, 18 Apr 2025 14:35:49 -0700 Subject: [PATCH 4/4] More prep for 2.1.10+ (#1301) --- .../kotlin/plugin/jdeps/k2/JdepsK2Utils.kt | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/k2/JdepsK2Utils.kt b/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/k2/JdepsK2Utils.kt index 11a5cd1dd..a9247e495 100644 --- a/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/k2/JdepsK2Utils.kt +++ b/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/k2/JdepsK2Utils.kt @@ -1,5 +1,7 @@ package io.bazel.kotlin.plugin.jdeps.k2 +import io.bazel.kotlin.plugin.jdeps.k2.RefCache.vbseClass +import io.bazel.kotlin.plugin.jdeps.k2.RefCache.vbseGetVirtualFileMethod import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement @@ -7,6 +9,19 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource private object RefCache { + val vbseClass: Class<*>? by lazy { + runCatching { + Class.forName("org.jetbrains.kotlin.fir.java.VirtualFileBasedSourceElement") + }.getOrNull() + } + + val vbseGetVirtualFileMethod by lazy { + vbseClass + ?.runCatching { + getMethod("getVirtualFile") + }?.getOrNull() + } + val jbseClass: Class<*>? by lazy { runCatching { Class.forName("org.jetbrains.kotlin.fir.java.JavaBinarySourceElement") @@ -28,8 +43,7 @@ private object RefCache { * @return whether class is provided by JSM runtime or not */ internal fun isJvmClass(className: String): Boolean = - className.startsWith("java") || - className.startsWith("modules/java.base/java/") + className.startsWith("java") || className.startsWith("modules/java.base/java/") internal fun DeserializedContainerSource.classId(): ClassId? = when (this) { @@ -43,6 +57,9 @@ internal fun SourceElement.binaryClass(): String? = binaryClass.location } else if (this is JvmPackagePartSource) { this.knownJvmBinaryClass?.location + } else if (vbseClass != null && vbseClass!!.isInstance(this)) { + val virtualFile = vbseGetVirtualFileMethod!!.invoke(this) + virtualFile?.javaClass!!.getMethod("getPath").invoke(virtualFile) as? String } else if (RefCache.jbseClass != null && RefCache.jbseClass!!.isInstance(this)) { val jClass = RefCache.jbseGetJavaClassMethod!!.invoke(this) val virtualFile = jClass!!.javaClass.getMethod("getVirtualFile").invoke(jClass)