Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/flutter_integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:

- uses: subosito/flutter-action@v2
with:
flutter-version: '3.24'
flutter-version: '3.29'
cache: true

- name: 'Run Flutter Driver tests'
Expand All @@ -65,4 +65,4 @@ jobs:
disable-animations: true
script: |
flutter pub get
cd test_integration && flutter drive
cd test_integration && flutter build apk && flutter drive
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
ruby 3.0.1
ruby 3.4.5
flutter 3.29.0
35 changes: 16 additions & 19 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
group 'io.ably.flutter.plugin'
version '1.0'
// Use the snapshot suffix to show that build artifacts are not shared.
// This Gradle file is used by Flutter to build itself.
version '1.0-SNAPSHOT'

buildscript {
repositories {
google()
mavenCentral() // for firebase-messaging
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:7.4.0'
classpath 'com.android.tools.build:gradle:8.12.1'
}
}

Expand All @@ -26,36 +28,25 @@ dependencies {
implementation 'io.ably:ably-android:1.2.40'

// https://firebase.google.com/docs/cloud-messaging/android/client
implementation 'com.google.firebase:firebase-messaging:23.0.4'

// https://github.com/google/desugar_jdk_libs
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
implementation 'com.google.firebase:firebase-messaging:23.0.6'
}

android {
compileSdkVersion 34
// older version of flutter sdk doesn't provide `compileSdkVersion` defaults to 34
compileSdkVersion flutter.compileSdkVersion ?: 34

// Conditional for compatibility with AGP <4.2.
if (project.android.hasProperty("namespace")) {
namespace 'io.ably.flutter.plugin'
}

// Require Java language level 8 so we can use Method References (used with Lambdas)
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8

// Flag to enable Java 8 language APIs while supporting to older SDK Versions
coreLibraryDesugaringEnabled true
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

defaultConfig {
minSdkVersion 19

// Required when setting minSdkVersion to 20 or lower so we can use
// the Java 8 language APIs as mentioned here:
// https://developer.android.com/studio/write/java8-support#library-desugaring
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
lintOptions {
Expand All @@ -66,4 +57,10 @@ android {
}
}

gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
}
}

apply from: file("./ably-agent.gradle")
6 changes: 3 additions & 3 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ android {
compileOptions {
coreLibraryDesugaringEnabled true

sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai This change shouldn't affect older android platforms right

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🌐 Web query:

Android Java 17 sourceCompatibility desugaring backward compatibility older Android versions

💡 Result:

Short answer: You can set sourceCompatibility = JavaVersion.VERSION_17 and compile with JDK 17, but to run Java 17 APIs on older Android versions you must use API desugaring (coreLibraryDesugaring). Not every Java 17 runtime API is desugared; language syntax features that compile to bytecode (records, sealed classes, pattern matching, switch expressions) are handled at compile-time, but newer standard-library APIs (java.time, streams, etc.) require the desugaring library and a sufficiently recent Android Gradle Plugin (AGP). [1][2][3]

What to do (minimal working setup)

  • Set Java 17 in module build.gradle:
    android { compileOptions { sourceCompatibility JavaVersion.VERSION_17; targetCompatibility JavaVersion.VERSION_17 }
    kotlinOptions { jvmTarget = "17" } }
    (or equivalent Kotlin DSL). [1]

  • Enable core library desugaring and add the desugar library dependency:
    android { compileOptions { coreLibraryDesugaringEnabled true } }
    dependencies { coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:" }
    Use an AGP version that supports the desugaring you need (AGP 4.0+ added API desugaring; recent AGP versions expand Java 11+ support). [2][4]

Caveats / compatibility

  • Desugaring provides many Java 8–11 APIs and a growing set beyond, but it does not automatically cover every Java 17 API; check the Android desugaring API tables to confirm specific classes/methods you plan to use. [3]
  • Some JVM-level features that rely on platform internals (MethodHandle.invokeExact, some reflection behaviors) may require minSdkVersion constraints or won't work on very old devices. [2]
  • Android 14 introduced broader native Java 17 support on-device, but for apps targeting older Android releases rely on desugaring at build time. [1][4]

References

  • Java versions in Android builds (sourceCompatibility / jvmTarget). [1]
  • Java 8+ language & API desugaring overview (how to enable coreLibraryDesugaring). [2]
  • API tables listing which stdlib classes are available via desugaring. [3]
  • AGP 4.0 release notes / desugaring history. [4]

If you want, I can (a) produce a paste-ready Gradle snippet with the latest desugar_jdk_libs artifact version, or (b) check which specific Java 17 APIs you plan to use and verify whether they're desugared.


@sacOO7, this change should not affect older Android platforms because the code properly enables desugaring. Here's why:

What happens with Java 17:

  1. Language features (like records, sealed classes, pattern matching) are compiled to bytecode at build-time and work on all Android versions that meet your minSdk requirement.

  2. Standard library APIs (like java.time, streams, etc.) require runtime support. This is where desugaring comes in.

Why it's safe in this PR:

The code correctly configures desugaring on Line 15:

  • coreLibraryDesugaringEnabled = true
  • Includes the dependency: coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'

This means the Android Gradle Plugin will automatically backport Java 17 APIs to work on older Android versions at build time.

Minor caveats:

  • Not every Java 17 API is desugared (though most common ones are)
  • Some JVM-specific features requiring deep platform internals may still need higher minSdk values

Since this is the example app and you're already using desugaring in both the example and test_integration apps, backward compatibility is maintained. The upgrade from AGP 7.4.0 to 8.12.1 also improves the desugaring support.

}

kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
jvmTarget = JavaVersion.VERSION_17
}

defaultConfig {
Expand Down
2 changes: 1 addition & 1 deletion example/android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.7.0" apply false
id "org.jetbrains.kotlin.android" version "1.8.22" apply false
id "org.jetbrains.kotlin.android" version "2.2.20" apply false
id "com.google.gms.google-services" version "4.3.10" apply false
}

Expand Down
13 changes: 10 additions & 3 deletions test_integration/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ android {
ndkVersion = flutter.ndkVersion

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
coreLibraryDesugaringEnabled true

sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
jvmTarget = JavaVersion.VERSION_17
}

defaultConfig {
Expand All @@ -42,3 +44,8 @@ android {
flutter {
source = "../.."
}

dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
}

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
5 changes: 3 additions & 2 deletions test_integration/android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ pluginManagement {

plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.4.0" apply false
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
id "com.android.application" version "8.7.0" apply false
id "org.jetbrains.kotlin.android" version "2.2.20" apply false
id "com.google.gms.google-services" version "4.3.10" apply false
}

include ":app"
Loading