Repository navigation
chore(build): Compile with a JDK 21 toolchain and upgrade Mockito and Error Prone #6242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
01efed6
8ff189d
3dc76c0
26b8a60
9788085
f6de52d
6e81176
1c7fbf3
5c8907d
7bd342c
37b01cf
d663f01
445f5e4
2de047f
561324b
2c629ba
ddae2a9
aaa1ef0
fef4772
61c4352
c667f66
4d4654d
982954a
38288e8
e387384
a2345fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| package io.sentry.gradle | ||
|
|
||
| import com.android.build.gradle.BaseExtension | ||
| import org.gradle.api.JavaVersion | ||
| import org.gradle.api.Plugin | ||
| import org.gradle.api.Project | ||
| import org.gradle.api.artifacts.VersionCatalogsExtension | ||
| import org.gradle.api.plugins.JavaBasePlugin | ||
| import org.gradle.api.plugins.JavaPluginExtension | ||
| import org.gradle.api.tasks.compile.JavaCompile | ||
| import org.gradle.jvm.toolchain.JavaLanguageVersion | ||
| import org.jetbrains.kotlin.gradle.dsl.JvmTarget | ||
| import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension | ||
| import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile | ||
|
|
||
| /** The JDK every module compiles and tests with, whatever JDK runs Gradle. */ | ||
| private val BUILD_JDK = JavaLanguageVersion.of(21) | ||
|
|
||
| /** The level the SDK publishes, so that Java 8 consumers can still use it. */ | ||
| private val PUBLISHED_JAVA_VERSION = JavaVersion.VERSION_1_8 | ||
|
|
||
| /** | ||
| * Holds every toolchain, bytecode level decision and compilation option of a module. It does the | ||
| * following | ||
| * - sample apps target the build JDK (21) | ||
| * - unit test code will target the build JDK (21) (required for Mockito 5) | ||
| * - published JVM modules main code pins the Java 1.8 release, for Java and for Kotlin | ||
| * - published Android modules main code targets Java 1.8 | ||
| * - minSdk is set for Android libraries | ||
| */ | ||
| class JdkTargetConvention : Plugin<Project> { | ||
| override fun apply(project: Project) { | ||
| project.plugins.withType(JavaBasePlugin::class.java) { | ||
| project.extensions.getByType(JavaPluginExtension::class.java).toolchain { | ||
| languageVersion.set(BUILD_JDK) | ||
| } | ||
| } | ||
|
|
||
| project.plugins.withId("com.vanniktech.maven.publish") { | ||
| // Only works for non-android modules | ||
| // See https://issuetracker.google.com/issues/278800528 | ||
| project.plugins.withId("java-library") { | ||
| project.tasks.named("compileJava", JavaCompile::class.java) { | ||
| options.release.set(PUBLISHED_JAVA_VERSION.majorVersion.toInt()) | ||
| } | ||
| } | ||
| // -Xjdk-release is the Kotlin counterpart of release: without it Kotlin resolves against the | ||
| // build JDK and happily compiles e.g. Files.readString() into Java 8 bytecode. The version | ||
| // follows jvmTarget, which the modules that publish a higher level set themselves. | ||
| project.plugins.withId("org.jetbrains.kotlin.jvm") { | ||
| project.tasks.named("compileKotlin", KotlinJvmCompile::class.java) { | ||
| compilerOptions.freeCompilerArgs.add( | ||
| compilerOptions.jvmTarget.map { "-Xjdk-release=${it.target}" } | ||
| ) | ||
| } | ||
| } | ||
| } | ||
|
cursor[bot] marked this conversation as resolved.
|
||
|
|
||
| project.plugins.withId("com.android.library") { | ||
| val android = project.extensions.getByType(BaseExtension::class.java) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we have some production kotlin code. do you know if this sets the JDK compatibility on that? I looked at how ANdroidx does this might be worth copying. They notably don't set the toolchain anywhere in code. https://github.com/androidx/androidx/blob/95347b245f1527ec6856a3daa580a1c0abbddc11/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt#L492 |
||
| android.compileOptions { | ||
| sourceCompatibility = PUBLISHED_JAVA_VERSION | ||
| targetCompatibility = PUBLISHED_JAVA_VERSION | ||
| } | ||
| android.defaultConfig { aarMetadata { minCompileSdk = project.minSdk() } } | ||
| } | ||
|
|
||
| listOf("com.android.library", "com.android.application").forEach { pluginId -> | ||
| project.plugins.withId(pluginId) { project.targetBuildJdkForUnitTests() } | ||
| } | ||
| } | ||
|
|
||
| private fun Project.minSdk(): Int = | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh! fancy! |
||
| extensions | ||
| .getByType(VersionCatalogsExtension::class.java) | ||
| .named("libs") | ||
| .findVersion("minSdk") | ||
| .orElseThrow { IllegalStateException("libs.versions.minSdk is missing") } | ||
| .requiredVersion | ||
| .toInt() | ||
|
|
||
| /** | ||
| * Mockito 5 and mockito-kotlin 6 are built for Java 11, so test code - which is never published - | ||
| * cannot share the Java 8 target of the main code. AGP has no per variant compileOptions, so this | ||
| * goes through the Kotlin compilations: their compile task providers are configured after AGP | ||
| * wrote its own compileOptions, which an apply time configureEach would lose against. | ||
| */ | ||
| private fun Project.targetBuildJdkForUnitTests() { | ||
| plugins.withId("org.jetbrains.kotlin.android") { | ||
| extensions | ||
| .getByType(KotlinAndroidProjectExtension::class.java) | ||
| .target | ||
| .compilations | ||
| .configureEach { | ||
| if (name.endsWith("UnitTest")) { | ||
| compileTaskProvider.configure { | ||
| compilerOptions.jvmTarget.set(JvmTarget.fromTarget(BUILD_JDK.toString())) | ||
| } | ||
| compileJavaTaskProvider?.configure { | ||
| sourceCompatibility = BUILD_JDK.toString() | ||
| targetCompatibility = BUILD_JDK.toString() | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,3 @@ | ||
| import org.jetbrains.kotlin.gradle.tasks.KotlinCompile | ||
|
|
||
| plugins { | ||
| `kotlin-dsl` | ||
| } | ||
|
|
||
| tasks.withType<KotlinCompile>().configureEach { | ||
|
markushi marked this conversation as resolved.
|
||
| compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i was going to ask why this line exists but then i saw your other comment.
i think this is fragile since it relies on precise task namings. i don't think this would match
compileReleaseJavafor example meaning that these tasks are not set properly: https://scans.gradle.com/s/mom72s36qrefi/timeline?name=compileReleaseJava