From 6a85d7deecead082722d51ef1c1d8c0fa2621783 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Jun 2026 23:09:42 +0000 Subject: [PATCH 1/4] Update jacoco to v0.8.15 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dc09e0af8..0639b5fb6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ # When upgrading JaCoCo to a newer version, make sure to # check the comment in the OpenAnalyzer.java, JaCoCoPreMain.java and CachingInstructionsBuilder.java # and update the internal_xxxxxx hash included in the imports in LenientCoverageTransformer.java and JaCoCoPreMain.java. -jacoco = "0.8.14" +jacoco = "0.8.15" # We need to stay on the 1.3.x release line as 1.4.x requires Java 11 logback = "1.3.16" retrofit = "3.0.0" From 309e8022790c5c06cc3c2fa9766c30c6cf5cc366 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Jun 2026 23:09:36 +0000 Subject: [PATCH 2/4] Update dependency jacoco to v0.8.15 --- buildSrc/src/main/kotlin/com.teamscale.coverage.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/com.teamscale.coverage.gradle.kts b/buildSrc/src/main/kotlin/com.teamscale.coverage.gradle.kts index ba582a656..84605fd9e 100644 --- a/buildSrc/src/main/kotlin/com.teamscale.coverage.gradle.kts +++ b/buildSrc/src/main/kotlin/com.teamscale.coverage.gradle.kts @@ -4,7 +4,7 @@ plugins { } jacoco { - toolVersion = "0.8.14" + toolVersion = "0.8.15" } tasks.jacocoTestReport { From ea4e88b82da707c7b0fa9d44941b289a1d9a117a Mon Sep 17 00:00:00 2001 From: Florian Dreier Date: Sun, 7 Jun 2026 06:12:44 +0200 Subject: [PATCH 3/4] Apply post-upgrade adjustments for JaCoCo 0.8.15 Update the shaded internal package hash in JaCoCoPreMain and LenientCoverageTransformer, port the upstream Analyzer change (synthetic check replaced with package-info check) into OpenAnalyzer, and add a changelog entry for the user-visible Java 26/27 support. Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 1 + .../teamscale/jacoco/agent/JaCoCoPreMain.java | 18 +++++++++--------- .../jacoco/agent/LenientCoverageTransformer.kt | 10 +++++----- .../teamscale/report/jacoco/OpenAnalyzer.java | 2 +- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7c6bbd00..4a41d6772 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ We use [semantic versioning](http://semver.org/): - PATCH version when you make backwards compatible bug fixes. # Next version +- [feature] _agent_: Added official support for Java 26 and experimental support for Java 27 (via JaCoCo 0.8.15) # 36.5.2 - [security fix] _agent_: The Teamscale access token was logged in clear text in DEBUG-level logs (e.g., when `debug=true` was set) and in the WARN-level log emitted when multiple `-javaagent` arguments are present. The token is now obfuscated in those logs as well, matching INFO-level behavior. diff --git a/agent/src/main/java/com/teamscale/jacoco/agent/JaCoCoPreMain.java b/agent/src/main/java/com/teamscale/jacoco/agent/JaCoCoPreMain.java index 4ad794ed2..87219cf5b 100644 --- a/agent/src/main/java/com/teamscale/jacoco/agent/JaCoCoPreMain.java +++ b/agent/src/main/java/com/teamscale/jacoco/agent/JaCoCoPreMain.java @@ -13,15 +13,15 @@ package com.teamscale.jacoco.agent; -import org.jacoco.agent.rt.internal_29a6edd.Agent; -import org.jacoco.agent.rt.internal_29a6edd.AgentModule; -import org.jacoco.agent.rt.internal_29a6edd.CoverageTransformer; -import org.jacoco.agent.rt.internal_29a6edd.IExceptionLogger; -import org.jacoco.agent.rt.internal_29a6edd.PreMain; -import org.jacoco.agent.rt.internal_29a6edd.core.runtime.AgentOptions; -import org.jacoco.agent.rt.internal_29a6edd.core.runtime.IRuntime; -import org.jacoco.agent.rt.internal_29a6edd.core.runtime.InjectedClassRuntime; -import org.jacoco.agent.rt.internal_29a6edd.core.runtime.ModifiedSystemClassRuntime; +import org.jacoco.agent.rt.internal_bac9136.Agent; +import org.jacoco.agent.rt.internal_bac9136.AgentModule; +import org.jacoco.agent.rt.internal_bac9136.CoverageTransformer; +import org.jacoco.agent.rt.internal_bac9136.IExceptionLogger; +import org.jacoco.agent.rt.internal_bac9136.PreMain; +import org.jacoco.agent.rt.internal_bac9136.core.runtime.AgentOptions; +import org.jacoco.agent.rt.internal_bac9136.core.runtime.IRuntime; +import org.jacoco.agent.rt.internal_bac9136.core.runtime.InjectedClassRuntime; +import org.jacoco.agent.rt.internal_bac9136.core.runtime.ModifiedSystemClassRuntime; import org.slf4j.Logger; import java.lang.instrument.Instrumentation; diff --git a/agent/src/main/kotlin/com/teamscale/jacoco/agent/LenientCoverageTransformer.kt b/agent/src/main/kotlin/com/teamscale/jacoco/agent/LenientCoverageTransformer.kt index dd9094e71..e1bd339a6 100644 --- a/agent/src/main/kotlin/com/teamscale/jacoco/agent/LenientCoverageTransformer.kt +++ b/agent/src/main/kotlin/com/teamscale/jacoco/agent/LenientCoverageTransformer.kt @@ -1,15 +1,15 @@ package com.teamscale.jacoco.agent -import org.jacoco.agent.rt.internal_29a6edd.CoverageTransformer -import org.jacoco.agent.rt.internal_29a6edd.IExceptionLogger -import org.jacoco.agent.rt.internal_29a6edd.core.runtime.AgentOptions -import org.jacoco.agent.rt.internal_29a6edd.core.runtime.IRuntime +import org.jacoco.agent.rt.internal_bac9136.CoverageTransformer +import org.jacoco.agent.rt.internal_bac9136.IExceptionLogger +import org.jacoco.agent.rt.internal_bac9136.core.runtime.AgentOptions +import org.jacoco.agent.rt.internal_bac9136.core.runtime.IRuntime import org.slf4j.Logger import java.lang.instrument.IllegalClassFormatException import java.security.ProtectionDomain /** - * A class file transformer which delegates to the JaCoCo [org.jacoco.agent.rt.internal_29a6edd.CoverageTransformer] to do the actual instrumentation, + * A class file transformer which delegates to the JaCoCo [org.jacoco.agent.rt.internal_bac9136.CoverageTransformer] to do the actual instrumentation, * but treats instrumentation errors e.g. due to unsupported class file versions more lenient by only logging them, but * not bailing out completely. Those unsupported classes will not be instrumented and will therefore not be contained in * the collected coverage report. diff --git a/report-generator/src/main/java/com/teamscale/report/jacoco/OpenAnalyzer.java b/report-generator/src/main/java/com/teamscale/report/jacoco/OpenAnalyzer.java index a341522b5..7925af6fb 100644 --- a/report-generator/src/main/java/com/teamscale/report/jacoco/OpenAnalyzer.java +++ b/report-generator/src/main/java/com/teamscale/report/jacoco/OpenAnalyzer.java @@ -113,7 +113,7 @@ protected void analyzeClass(final byte[] source) { if ((reader.getAccess() & Opcodes.ACC_MODULE) != 0) { return; } - if ((reader.getAccess() & Opcodes.ACC_SYNTHETIC) != 0) { + if (reader.getClassName().endsWith("/package-info")) { return; } final ClassVisitor visitor = createAnalyzingVisitor(classId, From c8f557f863a3658ef8819708380fcceff5534dc2 Mon Sep 17 00:00:00 2001 From: Florian Dreier Date: Sun, 7 Jun 2026 07:06:03 +0200 Subject: [PATCH 4/4] Extend Kotlin string transformer to cover ClassAnalyzer JaCoCo 0.8.15 inlines the Lkotlin/Metadata; descriptor constant from Filters into ClassAnalyzer.visitAnnotation, one package above the filter/ subpackage. The shadow build relocates kotlin to shadow.kotlin, which mangles this literal; without the revert, ClassAnalyzer no longer recognizes the Kotlin metadata annotation, the SMAP is never parsed, and KotlinInlineFilter is silently disabled. Broaden the post-build transformer's path match accordingly. Co-Authored-By: Claude Opus 4.7 (1M context) --- buildSrc/src/main/kotlin/KotlinStringTransformer.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/kotlin/KotlinStringTransformer.kt b/buildSrc/src/main/kotlin/KotlinStringTransformer.kt index 42d286bbc..e893bf872 100644 --- a/buildSrc/src/main/kotlin/KotlinStringTransformer.kt +++ b/buildSrc/src/main/kotlin/KotlinStringTransformer.kt @@ -9,7 +9,10 @@ import kotlin.io.path.pathString /** * Reverts the transformation from "kotlin" to "shadow/kotlin" within strings of - * "org/jacoco/core/internal/analysis/filter" to make JaCoCo correctly process Kotlin class files. + * "org/jacoco/core/internal/analysis" (including the "filter" subpackage) to make JaCoCo correctly + * process Kotlin class files. Since JaCoCo 0.8.15 the kotlin.Metadata descriptor literal is also + * inlined into ClassAnalyzer (in the parent "analysis" package), so the filter subpackage alone is + * not enough. */ fun revertKotlinPackageChanges(archiveFile: Provider) { val zip = archiveFile.get().asFile.toPath() @@ -37,7 +40,7 @@ private fun transformClass(file: Path) { } private fun shouldTransform(path: String): Boolean { - return path.contains("org/jacoco/core/internal/analysis/filter") + return path.contains("org/jacoco/core/internal/analysis") } private class StringReplacerClassVisitor(classNode: ClassVisitor?) : ClassVisitor(Opcodes.ASM9, classNode) {