From 7e649bf0f3ae60a4ca6f9d8aa7a4bb74449058a7 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Sun, 31 Mar 2024 06:46:41 -0400 Subject: [PATCH 1/8] fix: remove ShadowJar plugin - unable to control file dates of archive entries --- brut.apktool/apktool-cli/build.gradle.kts | 1 - build.gradle.kts | 1 - gradle/libs.versions.toml | 4 ---- 3 files changed, 6 deletions(-) diff --git a/brut.apktool/apktool-cli/build.gradle.kts b/brut.apktool/apktool-cli/build.gradle.kts index f90708363d..11d3052b84 100644 --- a/brut.apktool/apktool-cli/build.gradle.kts +++ b/brut.apktool/apktool-cli/build.gradle.kts @@ -3,7 +3,6 @@ import proguard.gradle.ProGuardTask val apktoolVersion: String by rootProject.extra plugins { - alias(libs.plugins.shadow) application } diff --git a/build.gradle.kts b/build.gradle.kts index ebef217920..4d37f83231 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -55,7 +55,6 @@ if ("release" !in gradle.startParameter.taskNames) { } plugins { - alias(libs.plugins.shadow) `java-library` `maven-publish` signing diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 35bf9d9052..7b8973dd58 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,6 @@ commons_text = "1.11.0" guava = "32.0.1-jre" junit = "4.13.2" proguard = "7.4.2" -shadow = "8.1.1" smali = "3.0.5" xmlpull = "1.1.4c" xmlunit = "2.9.1" @@ -24,6 +23,3 @@ proguard = { module = "com.guardsquare:proguard-gradle", version.ref = "proguard smali = { module = "com.android.tools.smali:smali", version.ref = "smali" } xmlpull = { module = "xpp3:xpp3", version.ref = "xmlpull" } xmlunit = { module = "org.xmlunit:xmlunit-legacy", version.ref = "xmlunit" } - -[plugins] -shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } From a65a5da021c4770462ea8b10b9bbba76371d053d Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Sun, 31 Mar 2024 06:46:52 -0400 Subject: [PATCH 2/8] refactor: use native Gradle "fatJar" method --- brut.apktool/apktool-cli/build.gradle.kts | 26 ++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/brut.apktool/apktool-cli/build.gradle.kts b/brut.apktool/apktool-cli/build.gradle.kts index 11d3052b84..bdeb705028 100644 --- a/brut.apktool/apktool-cli/build.gradle.kts +++ b/brut.apktool/apktool-cli/build.gradle.kts @@ -27,10 +27,9 @@ application { tasks.run.get().workingDir = file(System.getProperty("user.dir")) } -tasks.withType { - manifest { - attributes["Main-Class"] = "brut.apktool.Main" - } +tasks.withType().configureEach { + isPreserveFileTimestamps = false + isReproducibleFileOrder = true } tasks.register("cleanOutputDirectory") { @@ -39,8 +38,23 @@ tasks.register("cleanOutputDirectory") { }) } +tasks.create("shadowJar", Jar::class) { + dependsOn("build") + group = "build" + description = "Creates a single executable JAR with all dependencies" + manifest.attributes["Main-Class"] = "brut.apktool.Main" + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + + val dependencies = configurations + .runtimeClasspath + .get() + .map(::zipTree) + + from(dependencies) + with(tasks.jar.get()) +} + tasks.register("proguard") { - dependsOn("cleanOutputDirectory") dependsOn("shadowJar") injars(tasks.named("shadowJar").get().outputs.files) @@ -70,3 +84,5 @@ tasks.register("proguard") { val outPath = "build/libs/apktool-$apktoolVersion.jar" outjars(outPath) } + +tasks.getByPath(":release").dependsOn("proguard") From 54276502f92ecfd654b8dd6688b72e8c13e6cf59 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Tue, 2 Apr 2024 07:06:58 -0400 Subject: [PATCH 3/8] refactor: drop proguard for r8 --- brut.apktool/apktool-cli/build.gradle.kts | 60 +++++++-------------- brut.apktool/apktool-cli/proguard-rules.pro | 7 +++ gradle/libs.versions.toml | 4 +- 3 files changed, 29 insertions(+), 42 deletions(-) create mode 100644 brut.apktool/apktool-cli/proguard-rules.pro diff --git a/brut.apktool/apktool-cli/build.gradle.kts b/brut.apktool/apktool-cli/build.gradle.kts index bdeb705028..f40d1232c8 100644 --- a/brut.apktool/apktool-cli/build.gradle.kts +++ b/brut.apktool/apktool-cli/build.gradle.kts @@ -1,24 +1,15 @@ -import proguard.gradle.ProGuardTask - val apktoolVersion: String by rootProject.extra plugins { application } -// Buildscript is deprecated, but the alternative approach does not support expanded properties -// https://github.com/gradle/gradle/issues/9830 -// So we must hard-code the version here. -buildscript { - dependencies { - // Proguard doesn't support plugin DSL - https://github.com/Guardsquare/proguard/issues/225 - classpath(libs.proguard) - } -} +val r8: Configuration by configurations.creating dependencies { implementation(libs.commons.cli) implementation(project(":brut.apktool:apktool-lib")) + r8(libs.r8) } application { @@ -38,7 +29,7 @@ tasks.register("cleanOutputDirectory") { }) } -tasks.create("shadowJar", Jar::class) { +val shadowJar = tasks.create("shadowJar", Jar::class) { dependsOn("build") group = "build" description = "Creates a single executable JAR with all dependencies" @@ -54,35 +45,24 @@ tasks.create("shadowJar", Jar::class) { with(tasks.jar.get()) } -tasks.register("proguard") { +tasks.register("proguard") { dependsOn("shadowJar") - injars(tasks.named("shadowJar").get().outputs.files) - - val javaHome = System.getProperty("java.home") - if (JavaVersion.current() <= JavaVersion.VERSION_1_8) { - libraryjars("$javaHome/lib/jce.jar") - libraryjars("$javaHome/lib/rt.jar") - } else { - libraryjars(mapOf("jarfilter" to "!**.jar", "filter" to "!module-info.class"), - { - "$javaHome/jmods/" - } - ) - } - - dontobfuscate() - dontoptimize() - - keep("class brut.apktool.Main { public static void main(java.lang.String[]); }") - keepclassmembers("enum * { public static **[] values(); public static ** valueOf(java.lang.String); }") - dontwarn("com.google.common.base.**") - dontwarn("com.google.common.collect.**") - dontwarn("com.google.common.util.**") - dontwarn("javax.xml.xpath.**") - dontnote("**") - - val outPath = "build/libs/apktool-$apktoolVersion.jar" - outjars(outPath) + + val proguardRules = file("proguard-rules.pro") + + inputs.files(shadowJar, proguardRules) + outputs.file("build/libs/apktool-$apktoolVersion.jar") + + classpath(r8) + mainClass.set("com.android.tools.r8.R8") + + args = mutableListOf( + "--release", + "--classfile", + "--lib", javaLauncher.get().metadata.installationPath.toString(), + "--output", "build/libs/apktool-$apktoolVersion.jar", + "--pg-conf", proguardRules.toString(), + ) } tasks.getByPath(":release").dependsOn("proguard") diff --git a/brut.apktool/apktool-cli/proguard-rules.pro b/brut.apktool/apktool-cli/proguard-rules.pro new file mode 100644 index 0000000000..24ef7b0b1f --- /dev/null +++ b/brut.apktool/apktool-cli/proguard-rules.pro @@ -0,0 +1,7 @@ +-keep class brut.apktool.Main { + public static void main(java.lang.String[]); +} +-keepclassmembers enum * { + static **[] values(); + static ** valueOf(java.lang.String); +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7b8973dd58..2fd71c9cfc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ commons_lang3 = "3.14.0" commons_text = "1.11.0" guava = "32.0.1-jre" junit = "4.13.2" -proguard = "7.4.2" +r8 = "8.3.37" smali = "3.0.5" xmlpull = "1.1.4c" xmlunit = "2.9.1" @@ -19,7 +19,7 @@ commons_lang3 = { module = "org.apache.commons:commons-lang3", version.ref = "co commons_text = { module = "org.apache.commons:commons-text", version.ref = "commons_text" } guava = { module = "com.google.guava:guava", version.ref = "guava" } junit = { module = "junit:junit", version.ref = "junit" } -proguard = { module = "com.guardsquare:proguard-gradle", version.ref = "proguard" } +r8 = { module = "com.android.tools:r8", version.ref = "r8" } smali = { module = "com.android.tools.smali:smali", version.ref = "smali" } xmlpull = { module = "xpp3:xpp3", version.ref = "xmlpull" } xmlunit = { module = "org.xmlunit:xmlunit-legacy", version.ref = "xmlunit" } From 2b2338919c022af3e89034afe8ecbe8db8fda78f Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Wed, 3 Apr 2024 06:42:58 -0400 Subject: [PATCH 4/8] fix: wire up R8 --- brut.apktool/apktool-cli/build.gradle.kts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/brut.apktool/apktool-cli/build.gradle.kts b/brut.apktool/apktool-cli/build.gradle.kts index f40d1232c8..05ac826c9c 100644 --- a/brut.apktool/apktool-cli/build.gradle.kts +++ b/brut.apktool/apktool-cli/build.gradle.kts @@ -31,6 +31,8 @@ tasks.register("cleanOutputDirectory") { val shadowJar = tasks.create("shadowJar", Jar::class) { dependsOn("build") + dependsOn("cleanOutputDirectory") + group = "build" description = "Creates a single executable JAR with all dependencies" manifest.attributes["Main-Class"] = "brut.apktool.Main" @@ -49,8 +51,9 @@ tasks.register("proguard") { dependsOn("shadowJar") val proguardRules = file("proguard-rules.pro") + val originalJar = shadowJar.outputs.files.singleFile - inputs.files(shadowJar, proguardRules) + inputs.files(originalJar.toString(), proguardRules) outputs.file("build/libs/apktool-$apktoolVersion.jar") classpath(r8) @@ -59,9 +62,11 @@ tasks.register("proguard") { args = mutableListOf( "--release", "--classfile", + "--no-minification", "--lib", javaLauncher.get().metadata.installationPath.toString(), - "--output", "build/libs/apktool-$apktoolVersion.jar", + "--output", outputs.files.singleFile.toString(), "--pg-conf", proguardRules.toString(), + originalJar.toString() ) } From e50d494c7b42efe22e0bd97c69372e8507d3f403 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Wed, 3 Apr 2024 06:57:01 -0400 Subject: [PATCH 5/8] wip: remove fail-fast --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3de795e54a..50bf1a3c7b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,7 +66,7 @@ jobs: - analyze-windows-aapt name: Build/Test (JDK ${{ matrix.java }}, ${{ matrix.os }}) strategy: - fail-fast: true + fail-fast: false matrix: os: [ ubuntu-latest, macOS-latest, windows-latest ] java: [ 8, 11, 17, 21 ] From 4bfb9b380b3ff9c71e494166b6db5f39f469fc93 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Wed, 3 Apr 2024 20:23:23 -0400 Subject: [PATCH 6/8] Revert "wip: remove fail-fast" This reverts commit 5d005bf82e87c89efa5552ee8f8e9c0a569aea0d. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 50bf1a3c7b..3de795e54a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,7 +66,7 @@ jobs: - analyze-windows-aapt name: Build/Test (JDK ${{ matrix.java }}, ${{ matrix.os }}) strategy: - fail-fast: false + fail-fast: true matrix: os: [ ubuntu-latest, macOS-latest, windows-latest ] java: [ 8, 11, 17, 21 ] From f0358edc6b27abd5a0ff2485b341b69e8e0bd44d Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Wed, 3 Apr 2024 20:23:42 -0400 Subject: [PATCH 7/8] fix: suppress unused proguard keep messages --- brut.apktool/apktool-cli/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/brut.apktool/apktool-cli/build.gradle.kts b/brut.apktool/apktool-cli/build.gradle.kts index 05ac826c9c..fbd256f341 100644 --- a/brut.apktool/apktool-cli/build.gradle.kts +++ b/brut.apktool/apktool-cli/build.gradle.kts @@ -63,6 +63,7 @@ tasks.register("proguard") { "--release", "--classfile", "--no-minification", + "--map-diagnostics:UnusedProguardKeepRuleDiagnostic", "info", "none", "--lib", javaLauncher.get().metadata.installationPath.toString(), "--output", outputs.files.singleFile.toString(), "--pg-conf", proguardRules.toString(), From efb077fbc57b77d159ab6dcf41f928a06a180eb3 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Fri, 5 Apr 2024 06:12:09 -0400 Subject: [PATCH 8/8] fix: require java11+ for r8 --- brut.apktool/apktool-cli/build.gradle.kts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/brut.apktool/apktool-cli/build.gradle.kts b/brut.apktool/apktool-cli/build.gradle.kts index fbd256f341..50b8d8fb4a 100644 --- a/brut.apktool/apktool-cli/build.gradle.kts +++ b/brut.apktool/apktool-cli/build.gradle.kts @@ -50,6 +50,10 @@ val shadowJar = tasks.create("shadowJar", Jar::class) { tasks.register("proguard") { dependsOn("shadowJar") + onlyIf { + JavaVersion.current().isJava11Compatible + } + val proguardRules = file("proguard-rules.pro") val originalJar = shadowJar.outputs.files.singleFile