Skip to content

Commit fd1f598

Browse files
authored
[android][breaking]Target jvm 11 (#79)
## Summary Raises the library's JVM target from 1.8 to 11. Unblocks Mockito 5.x in tests. Bundles two adjacent Kotlin-2.0 cleanups while we're cutting the major version: closing the `Configuration.copy()` visibility leak, and migrating tests off deprecated `ShadowWebView.setCanGoBack`. ## Changes - `lib/build.gradle`: `compileOptions.sourceCompatibility` / `targetCompatibility` 1.8 → 11; Kotlin `jvmTarget` 1.8 → 11. - `lib/build.gradle`: Mockito core / kotlin / android 4.x → 5.x. `// noinspection NewerVersionAvailable` comments dropped — the JVM-target constraint they explained is gone. - `lib/src/main/.../Configuration.kt`: `@ConsistentCopyVisibility` annotation. Generated `copy()` now matches the primary constructor's `internal` visibility, closing the leak where consumers could bypass `internal constructor` via `cfg.copy(...)`. Kotlin 2.5 will make this an error anyway. - `lib/api/lib.api`: 2-line removal — `Configuration.copy(...)` and `copy$default(...)` no longer in the public AAR. - `lib/src/test/.../CheckoutDialogTest.kt`: `pushEntryToHistory(...)` replaces deprecated `setCanGoBack(true)` in two back-press tests. Single inline comment explains the pattern. - `CLAUDE.md`: JVM-target reference 1.8 → 11; Mockito 4.x pin note dropped. ## Why now - Major-version cut is the natural place to raise the JVM target. - Mockito 4.x has been pinned only because of the 1.8 floor; the `// noinspection` comments in `lib/build.gradle` flagged this explicitly. With JVM 11 in place, Mockito 5.x is unblocked. - The `Configuration.copy()` deprecation is a Kotlin 2.0+ language warning that will be a hard error in Kotlin 2.5. The breaking-API cost is small (only consumers calling `cfg.copy()` to construct dangling objects, which has no useful end-point) and the cost grows the longer we delay. - `ShadowWebView.setCanGoBack` is deprecated in Robolectric 4.16+ and slated for removal; the supported replacement is populating fake web history. ## Consumer impact - **JVM target**: consumers must build with JDK 11+. **This is the headline breaking change** — needs a release-notes line. - **API**: `Configuration.copy(...)` and `copy$default(...)` removed (see `lib.api`). Affects only consumers explicitly calling `.copy(...)` on a Configuration. Since there is no `setConfiguration(...)` setter on the library, those calls already produced dangling objects with no library-visible effect. ## Test plan - [ ] `./gradlew :lib:clean :lib:test :lib:detekt :lib:lintRelease :lib:apiCheck :lib:assembleRelease` — green - [ ] Sample app `./gradlew assembleDebug` from `samples/MobileBuyIntegration/` — green - [ ] `InteropTest` (Java consumer test) — all cases pass - [ ] CheckoutDialogTest back-press cases (with new history-populated path) — pass ## Stack Stacked on `compile-with-kotlin2.x`. Merge after that one lands, or as a combined major-version cut. ### Before you merge > [!IMPORTANT] > > - [ ] I've added tests to support my implementation > - [ ] I have read and agree with the [Contribution Guidelines](./CONTRIBUTING.md) > - [ ] I have read and agree with the [Code of Conduct](./CODE_OF_CONDUCT.md) > - [ ] I've updated the relevant platform README (`platforms/swift/README.md` and/or `platforms/android/README.md`) --- <details> <summary>Releasing a new Swift version?</summary> - [ ] I have bumped the version in `platforms/swift/ShopifyCheckoutKit.podspec` - [ ] I have bumped the version in `platforms/swift/Sources/ShopifyCheckoutKit/ShopifyCheckoutKit.swift` - [ ] I have updated `platforms/swift/CHANGELOG.md` - [ ] I have updated the SwiftPM/CocoaPods version snippets in `platforms/swift/README.md` (major version only) </details> <details> <summary>Releasing a new Android version?</summary> - [ ] I have bumped the `versionName` in `platforms/android/lib/build.gradle` - [ ] I have updated `platforms/android/CHANGELOG.md` - [ ] I have updated the Gradle/Maven version snippets in `platforms/android/README.md` </details> > [!TIP] > See the [Contributing documentation](./CONTRIBUTING.md) for the full release process per platform.
1 parent 79de76a commit fd1f598

5 files changed

Lines changed: 14 additions & 15 deletions

File tree

platforms/android/AGENTS.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ The sample is a separate Gradle composite (`samples/MobileBuyIntegration/setting
3434

3535
- Tests use **Robolectric** (`@RunWith(RobolectricTestRunner::class)`) to exercise Android framework code without a device.
3636
- Main-thread tasks are drained with `shadowOf(Looper.getMainLooper()).runToEndOfTasks()`. If a test involves posted work and seems flaky, check whether this is being called.
37-
- Assertion library is **AssertJ**; mocking is **Mockito** + **Mockito-Kotlin**. Don't introduce new assertion/mocking libraries without discussion.
38-
- Mockito is pinned at **4.x** intentionally — Mockito 5.x requires JVM target 11, and the library is on 1.8. Noted in `lib/build.gradle` with `// noinspection NewerVersionAvailable` comments.
37+
- Assertion library is **AssertJ**; mocking is **Mockito** + **Mockito-Kotlin**. Mockito is on 5.x because the library targets JVM 11. Don't introduce new assertion/mocking libraries without discussion.
3938
- Tests live in the same package as the class under test (file name: `ClassNameTest.kt`).
4039

4140
## Conventions
4241

4342
- **`-Xexplicit-api=strict`** is on (`lib/build.gradle`). Every public class, method, field, and property must have an explicit visibility modifier. "Accidentally public" is not a thing here. This is a consumer-protection rule — if you see a public-by-default declaration, it was deliberate.
4443
- **Max line length: 140** (detekt-enforced). Detekt config: `lib/detekt.config.yml`.
45-
- **Library JVM target: 1.8.** Intentional for consumer compatibility; don't raise without a major-version discussion.
44+
- **MIT license header required on every new source file.** Format: copy the top comment of any existing `.kt` or `.java` file in `lib/src/main` or `lib/src/test`. Enforced in CI via the repo-root `scripts/check_license_headers.rb`.
45+
- **Library JVM target: 11.** Consumers must build with JDK 11+ to consume the AAR. Raising further is a major-version discussion.
4646
- **Library Kotlin `apiVersion` / `languageVersion` are pinned at 2.0.** Set in `lib/build.gradle` so the AAR's bytecode stays consumable by Kotlin 2.0+ projects even though the compiler itself is on a newer 2.x. Bumping this pin is the consumer-facing breaking change, not bumping the compiler - treat it as a planned major-version event.
4747
- **Prefer generated protocol models.** Before adding hand-written protocol DTOs, check the generated models in `lib/src/main/java/com/shopify/checkoutkit/Models.kt` and the OpenRPC schema. Use generated UCP/ECP types for wire payloads; reserve local DTOs for Android-internal transport helpers that are not represented in the schema.
4848

platforms/android/lib/api/lib.api

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,8 +1091,6 @@ public final class com/shopify/checkoutkit/Configuration {
10911091
public final fun component1 ()Lcom/shopify/checkoutkit/ColorScheme;
10921092
public final fun component2 ()Lcom/shopify/checkoutkit/Platform;
10931093
public final fun component3 ()Lcom/shopify/checkoutkit/LogLevel;
1094-
public final fun copy (Lcom/shopify/checkoutkit/ColorScheme;Lcom/shopify/checkoutkit/Platform;Lcom/shopify/checkoutkit/LogLevel;)Lcom/shopify/checkoutkit/Configuration;
1095-
public static synthetic fun copy$default (Lcom/shopify/checkoutkit/Configuration;Lcom/shopify/checkoutkit/ColorScheme;Lcom/shopify/checkoutkit/Platform;Lcom/shopify/checkoutkit/LogLevel;ILjava/lang/Object;)Lcom/shopify/checkoutkit/Configuration;
10961094
public fun equals (Ljava/lang/Object;)Z
10971095
public final fun getColorScheme ()Lcom/shopify/checkoutkit/ColorScheme;
10981096
public final fun getLogLevel ()Lcom/shopify/checkoutkit/LogLevel;

platforms/android/lib/build.gradle

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ ext {
2424

2525
junit_version = '4.13.2'
2626
robolectric_version = '4.16.1'
27-
mockito_core_version = '4.11.0'
28-
mockito_kotlin_version = '4.1.0'
27+
mockito_core_version = '5.23.0'
28+
mockito_kotlin_version = '5.4.0'
2929
assertj_version = '3.27.7'
3030
awaitility_version = '4.3.0'
3131
detekt_formatting_version = '1.23.8'
@@ -63,8 +63,8 @@ android {
6363
}
6464
}
6565
compileOptions {
66-
sourceCompatibility JavaVersion.VERSION_1_8
67-
targetCompatibility JavaVersion.VERSION_1_8
66+
sourceCompatibility JavaVersion.VERSION_11
67+
targetCompatibility JavaVersion.VERSION_11
6868
}
6969
testOptions {
7070
unitTests.includeAndroidResources = true
@@ -89,7 +89,7 @@ android {
8989

9090
tasks.withType(KotlinJvmCompile).configureEach {
9191
compilerOptions {
92-
jvmTarget.set(JvmTarget.JVM_1_8)
92+
jvmTarget.set(JvmTarget.JVM_11)
9393
// Pin language/API version so bytecode stays consumable by Kotlin 2.0+ consumers
9494
// even though the compiler is on a newer 2.x. Kotlin 1.9 is deprecated by the 2.x
9595
// compiler, so 2.0 is the lowest pin we can hold without taking deprecation warnings;
@@ -108,11 +108,8 @@ dependencies {
108108

109109
testImplementation "junit:junit:$junit_version"
110110
testImplementation "org.robolectric:robolectric:$robolectric_version"
111-
// noinspection NewerVersionAvailable -- mockito 5 requires jvm target 1.11
112111
testImplementation "org.mockito:mockito-core:$mockito_core_version"
113-
// noinspection NewerVersionAvailable -- mockito 5 requires jvm target 1.11
114112
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version"
115-
// noinspection NewerVersionAvailable -- mockito 5 requires jvm target 1.11
116113
testImplementation "org.mockito:mockito-android:$mockito_core_version"
117114
testImplementation "org.assertj:assertj-core:$assertj_version"
118115
testImplementation "org.awaitility:awaitility:$awaitility_version"

platforms/android/lib/src/main/java/com/shopify/checkoutkit/Configuration.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package com.shopify.checkoutkit
55
*
66
* Allows specifying the colorScheme that should be used for checkout.
77
*/
8+
@ConsistentCopyVisibility
89
public data class Configuration internal constructor(
910
var colorScheme: ColorScheme = ColorScheme.Automatic(),
1011
var platform: Platform? = null,

platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutDialogTest.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,9 @@ class CheckoutDialogTest {
348348
val dialog = ShadowDialog.getLatestDialog() as CheckoutDialog
349349
val webView = dialog.currentWebView()
350350
webView.loadUrl("https://shopify.com/checkouts/c/abc/step2")
351-
shadowOf(webView).setCanGoBack(true)
351+
// ShadowWebView doesn't auto-track loadUrl in history; push two entries so canGoBack() returns true.
352+
shadowOf(webView).pushEntryToHistory("https://shopify.com/checkouts/c/abc")
353+
shadowOf(webView).pushEntryToHistory("https://shopify.com/checkouts/c/abc/step2")
352354
shadowOf(Looper.getMainLooper()).runToEndOfTasks()
353355

354356
dialog.onBackPressedDispatcher.onBackPressed()
@@ -368,7 +370,8 @@ class CheckoutDialogTest {
368370
val dialog = ShadowDialog.getLatestDialog() as CheckoutDialog
369371
val webView = dialog.currentWebView()
370372
webView.loadUrl("https://shopify.com/cn-12345/thank-you")
371-
shadowOf(webView).setCanGoBack(true)
373+
shadowOf(webView).pushEntryToHistory("https://shopify.com/checkouts/c/abc")
374+
shadowOf(webView).pushEntryToHistory("https://shopify.com/cn-12345/thank-you")
372375
shadowOf(Looper.getMainLooper()).runToEndOfTasks()
373376

374377
dialog.onBackPressedDispatcher.onBackPressed()

0 commit comments

Comments
 (0)