From 0989d277cd2a3a9599c92229efef2d2b9a091bc7 Mon Sep 17 00:00:00 2001 From: Agustin Grognetti Date: Tue, 25 Nov 2025 17:43:54 -0300 Subject: [PATCH 1/3] Update to Android Gradle Plugin 8.3.2 and SDK 34 Upgraded Android Gradle Plugin, Gradle wrapper, and dexcount plugin versions. Migrated all modules to use compileSdk 34 and targetSdk 34, added namespace declarations, and updated build configuration to match latest Gradle and Android standards. Improved build script structure and fixed deprecation warnings for Gradle tasks. --- build.gradle | 42 ++++++++++------- contract-tests/build.gradle | 8 ++-- example/build.gradle | 8 ++-- example/src/main/AndroidManifest.xml | 6 ++- gradle/wrapper/gradle-wrapper.properties | 4 +- launchdarkly-android-client-sdk/build.gradle | 48 ++++++++++++-------- shared-test-code/build.gradle | 8 ++-- 7 files changed, 73 insertions(+), 51 deletions(-) diff --git a/build.gradle b/build.gradle index c1cb43a1..ec4dee6c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,5 @@ import java.time.Duration +import com.android.build.gradle.BaseExtension // Top-level build file where you can add configuration options common to all sub-projects/modules. @@ -8,11 +9,11 @@ buildscript { google() } dependencies { - classpath('com.android.tools.build:gradle:7.1.1') + classpath('com.android.tools.build:gradle:8.3.2') // For displaying method/field counts when building with Gradle: // https://github.com/KeepSafe/dexcount-gradle-plugin - classpath("com.getkeepsafe.dexcount:dexcount-gradle-plugin:3.1.0") + classpath("com.getkeepsafe.dexcount:dexcount-gradle-plugin:4.0.0") // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -21,13 +22,15 @@ buildscript { plugins { id("java") - id("io.github.gradle-nexus.publish-plugin") version "1.1.0" + id("io.github.gradle-nexus.publish-plugin") version "1.3.0" } // Must be specified in root project for the gradle nexus publish plugin. group = "com.launchdarkly" -// Specified in the root project so Releaser's `publish-dry-run.sh` can see it in `./gradlew properties` -archivesBaseName = 'launchdarkly-android-client-sdk' +base { + // Specified in the root project so Releaser's `publish-dry-run.sh` can see it in `./gradlew properties` + archivesName = "launchdarkly-android-client-sdk" +} // Specified in gradle.properties version = version @@ -41,21 +44,13 @@ allprojects { } } -subprojects { - afterEvaluate { - configure(android.lintOptions) { - abortOnError = false - } - configure(android.compileOptions) { +def configureAndroidModule(Project project) { + project.extensions.configure(BaseExtension) { androidExt -> + androidExt.lint { abortOnError = false } + androidExt.compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } - gradle.projectsEvaluated { - tasks.withType(JavaCompile) { - // enable deprecation checks - options.compilerArgs << "-Xlint:deprecation" - } - } } } @@ -68,3 +63,16 @@ nexusPublishing { } } } + +subprojects { subproject -> + plugins.withId("com.android.application") { + configureAndroidModule(subproject) + } + plugins.withId("com.android.library") { + configureAndroidModule(subproject) + } + tasks.withType(JavaCompile).configureEach { + // enable deprecation checks + options.compilerArgs += "-Xlint:deprecation" + } +} diff --git a/contract-tests/build.gradle b/contract-tests/build.gradle index 8def8018..dde0df0c 100644 --- a/contract-tests/build.gradle +++ b/contract-tests/build.gradle @@ -5,13 +5,13 @@ plugins { } android { - compileSdkVersion(30) - buildToolsVersion = "30.0.3" + namespace "com.launchdarkly.sdktest" + compileSdk = 34 defaultConfig { applicationId = "com.launchdarkly.sdktest" - minSdkVersion(21) - targetSdkVersion(30) + minSdk = 21 + targetSdk = 34 versionCode = 1 versionName = "1.0" } diff --git a/example/build.gradle b/example/build.gradle index 4f2bbc71..9331d77f 100644 --- a/example/build.gradle +++ b/example/build.gradle @@ -5,13 +5,13 @@ plugins { } android { - compileSdkVersion(30) - buildToolsVersion = "30.0.3" + namespace "com.launchdarkly.example" + compileSdk = 34 defaultConfig { applicationId = "com.launchdarkly.example" - minSdkVersion(21) - targetSdkVersion(30) + minSdk = 21 + targetSdk = 34 versionCode = 1 versionName = "1.0" } diff --git a/example/src/main/AndroidManifest.xml b/example/src/main/AndroidManifest.xml index 2d7d67da..ae8f7179 100644 --- a/example/src/main/AndroidManifest.xml +++ b/example/src/main/AndroidManifest.xml @@ -6,7 +6,9 @@ - + @@ -15,4 +17,4 @@ - \ No newline at end of file + diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ad81be16..a57bc7ed 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Jan 11 09:20:17 PST 2018 +#Tue Nov 25 16:57:24 ART 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip diff --git a/launchdarkly-android-client-sdk/build.gradle b/launchdarkly-android-client-sdk/build.gradle index d46aa03c..12bc4a05 100644 --- a/launchdarkly-android-client-sdk/build.gradle +++ b/launchdarkly-android-client-sdk/build.gradle @@ -10,12 +10,12 @@ group = "com.launchdarkly" version = version android { - compileSdkVersion(30) - buildToolsVersion = "30.0.3" + namespace "com.launchdarkly.sdk.android" + compileSdk = 34 defaultConfig { - minSdkVersion(21) - targetSdkVersion(30) + minSdk = 21 + targetSdk = 34 // at some point between android gradle 3.1.0 and 4.x.x the versionName field in this dsl // stopped generating the BuildConfig::VERSION_NAME field in the end java // classpath. put this here to bring back that field @@ -33,8 +33,18 @@ android { execution = "ANDROIDX_TEST_ORCHESTRATOR" } - packagingOptions { - exclude("META-INF/**") + buildFeatures { + buildConfig = true + } + + publishing { + singleVariant("release") + } + + packaging { + resources { + excludes += ["META-INF/**"] + } } useLibrary("android.test.runner") @@ -109,7 +119,7 @@ dependencies { androidTestUtil("androidx.test:orchestrator:1.4.1") } -task javadoc(type: Javadoc) { +def androidJavadoc = tasks.register("javadoc", Javadoc) { // Include SDK sources source android.sourceSets.main.java.srcDirs // Include common library sources @@ -118,8 +128,8 @@ task javadoc(type: Javadoc) { include("**/*.java") - // Include classpaths for dependencies - afterEvaluate { + doFirst { + // Include classpaths for dependencies classpath += files(android.libraryVariants.collect { variant -> variant.javaCompileProvider.get().classpath.files }) @@ -131,14 +141,15 @@ task javadoc(type: Javadoc) { classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) } -task sourcesJar(type: Jar) { - classifier = "sources" +def sourcesJar = tasks.register("sourcesJar", Jar) { + archiveClassifier.set("sources") from android.sourceSets.main.java.srcDirs } -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = "javadoc" - from javadoc.destinationDir +def javadocJar = tasks.register("javadocJar", Jar) { + dependsOn(androidJavadoc) + archiveClassifier.set("javadoc") + from(androidJavadoc.map { it.destinationDir }) } tasks.withType(Javadoc) { @@ -152,19 +163,20 @@ tasks.withType(Javadoc) { } artifacts { - archives sourcesJar, javadocJar + add("archives", sourcesJar.get()) + add("archives", javadocJar.get()) } afterEvaluate { publishing { publications { release(MavenPublication) { - from components.release + from components["release"] artifactId = "launchdarkly-android-client-sdk" - artifact(sourcesJar) - artifact(javadocJar) + artifact(sourcesJar.get()) + artifact(javadocJar.get()) pom { name = "LaunchDarkly SDK for Android" diff --git a/shared-test-code/build.gradle b/shared-test-code/build.gradle index 9cd5f9f6..4b3fe32e 100644 --- a/shared-test-code/build.gradle +++ b/shared-test-code/build.gradle @@ -17,12 +17,12 @@ ext.versions = [ ] android { - compileSdkVersion(30) - buildToolsVersion = "30.0.3" + namespace "com.launchdarkly.sdk.android.sharedtest" + compileSdk = 34 defaultConfig { - minSdkVersion(21) - targetSdkVersion(30) + minSdk = 21 + targetSdk = 34 } } From c766238380e0fae3e47388dd58693a3638e1dbf6 Mon Sep 17 00:00:00 2001 From: Agustin Grognetti Date: Wed, 26 Nov 2025 00:00:29 -0300 Subject: [PATCH 2/3] Update build configs and ProGuard rules for Android Added ProGuard rules to contract-tests and example modules to suppress warnings for error-prone annotations. Improved build.gradle files to support reflection for tests and enhanced Javadoc generation with proper boot classpath handling. Cleaned up AndroidManifest.xml files by removing explicit package attributes. --- build.gradle | 4 ++++ contract-tests/proguard-rules.pro | 2 ++ contract-tests/src/main/AndroidManifest.xml | 3 +-- example/build.gradle | 1 + example/proguard-rules.pro | 2 ++ example/src/main/AndroidManifest.xml | 3 +-- launchdarkly-android-client-sdk/build.gradle | 14 ++++++++++++-- .../src/main/AndroidManifest.xml | 3 +-- shared-test-code/src/main/AndroidManifest.xml | 3 +-- 9 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 contract-tests/proguard-rules.pro create mode 100644 example/proguard-rules.pro diff --git a/build.gradle b/build.gradle index ec4dee6c..a7a1c579 100644 --- a/build.gradle +++ b/build.gradle @@ -75,4 +75,8 @@ subprojects { subproject -> // enable deprecation checks options.compilerArgs += "-Xlint:deprecation" } + tasks.withType(Test).configureEach { + // Allow EasyMock/CGLIB to use reflection on Java base classes when running on newer JDKs. + jvmArgs += ["--add-opens", "java.base/java.lang=ALL-UNNAMED"] + } } diff --git a/contract-tests/proguard-rules.pro b/contract-tests/proguard-rules.pro new file mode 100644 index 00000000..8788708d --- /dev/null +++ b/contract-tests/proguard-rules.pro @@ -0,0 +1,2 @@ +# Allow compile-time-only error-prone annotations to be stripped without breaking shrink. +-dontwarn com.google.errorprone.annotations.** diff --git a/contract-tests/src/main/AndroidManifest.xml b/contract-tests/src/main/AndroidManifest.xml index 77c21cdd..ba035cb4 100644 --- a/contract-tests/src/main/AndroidManifest.xml +++ b/contract-tests/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + diff --git a/example/build.gradle b/example/build.gradle index 9331d77f..797ab8d8 100644 --- a/example/build.gradle +++ b/example/build.gradle @@ -19,6 +19,7 @@ android { buildTypes { release { minifyEnabled = true + proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") } } } diff --git a/example/proguard-rules.pro b/example/proguard-rules.pro new file mode 100644 index 00000000..8788708d --- /dev/null +++ b/example/proguard-rules.pro @@ -0,0 +1,2 @@ +# Allow compile-time-only error-prone annotations to be stripped without breaking shrink. +-dontwarn com.google.errorprone.annotations.** diff --git a/example/src/main/AndroidManifest.xml b/example/src/main/AndroidManifest.xml index ae8f7179..b9729d0f 100644 --- a/example/src/main/AndroidManifest.xml +++ b/example/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + diff --git a/launchdarkly-android-client-sdk/build.gradle b/launchdarkly-android-client-sdk/build.gradle index 12bc4a05..faae5bab 100644 --- a/launchdarkly-android-client-sdk/build.gradle +++ b/launchdarkly-android-client-sdk/build.gradle @@ -125,20 +125,30 @@ def androidJavadoc = tasks.register("javadoc", Javadoc) { // Include common library sources source configurations.commonDoc.collect { zipTree(it) } source "$buildDir/generated/source" + // Ensure generated BuildConfig is present before javadoc runs. + dependsOn("generateDebugBuildConfig", "generateReleaseBuildConfig") include("**/*.java") + if (options instanceof StandardJavadocDocletOptions) { + options.source = "8" + } + doFirst { // Include classpaths for dependencies classpath += files(android.libraryVariants.collect { variant -> variant.javaCompileProvider.get().classpath.files }) + // Add Android boot classpath for references to Android OS classes. + def bootClasspath = files(android.bootClasspath) + classpath += bootClasspath + if (options instanceof StandardJavadocDocletOptions) { + options.bootClasspath = bootClasspath.files.toList() + } } // Include classpath for commonClasses configuration so Javadoc won't complain about java-sdk-common classes that // internally reference Jackson, which we don't use directly classpath += project.files(configurations.commonClasses.resolve()) - // Add Android boot classpath for references to Android OS classes. - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) } def sourcesJar = tasks.register("sourcesJar", Jar) { diff --git a/launchdarkly-android-client-sdk/src/main/AndroidManifest.xml b/launchdarkly-android-client-sdk/src/main/AndroidManifest.xml index fda680f9..221161fa 100644 --- a/launchdarkly-android-client-sdk/src/main/AndroidManifest.xml +++ b/launchdarkly-android-client-sdk/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + diff --git a/shared-test-code/src/main/AndroidManifest.xml b/shared-test-code/src/main/AndroidManifest.xml index dc60dbec..c5d956b6 100644 --- a/shared-test-code/src/main/AndroidManifest.xml +++ b/shared-test-code/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - +