Skip to content

Commit 4d46e62

Browse files
fix(client): r8 support
1 parent 6bf3387 commit 4d46e62

File tree

4 files changed

+61
-17
lines changed

4 files changed

+61
-17
lines changed

orb-kotlin-core/src/main/resources/META-INF/proguard/orb-kotlin-core.pro

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Jackson uses reflection and depends heavily on runtime attributes.
2-
-keepattributes
2+
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,*Annotation*
33

44
# Jackson uses Kotlin reflection utilities, which themselves use reflection to access things.
55
-keep class kotlin.reflect.** { *; }
@@ -17,13 +17,13 @@
1717
*;
1818
}
1919

20-
# Jackson uses reflection to access the default constructors of serializers and deserializers.
21-
-keepclassmembers class * extends com.withorb.api.core.BaseSerializer {
22-
<init>();
23-
}
24-
-keepclassmembers class * extends com.withorb.api.core.BaseDeserializer {
25-
<init>();
26-
}
20+
# Jackson uses reified type information to serialize and deserialize our classes (via `TypeReference`).
21+
-keep class com.fasterxml.jackson.core.type.TypeReference { *; }
22+
-keep class * extends com.fasterxml.jackson.core.type.TypeReference { *; }
23+
24+
# Jackson uses reflection to access our class serializers and deserializers.
25+
-keep @com.fasterxml.jackson.databind.annotation.JsonSerialize class com.withorb.api.** { *; }
26+
-keep @com.fasterxml.jackson.databind.annotation.JsonDeserialize class com.withorb.api.** { *; }
2727

2828
# Jackson uses reflection to serialize and deserialize our classes based on their constructors and annotated members.
2929
-keepclassmembers class com.withorb.api.** {

orb-kotlin-proguard-test/build.gradle.kts

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@ plugins {
44
}
55

66
buildscript {
7+
repositories {
8+
google()
9+
}
10+
711
dependencies {
812
classpath("com.guardsquare:proguard-gradle:7.4.2")
13+
classpath("com.android.tools:r8:8.3.37")
914
}
1015
}
1116

@@ -15,7 +20,6 @@ dependencies {
1520
testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3")
1621
testImplementation("org.assertj:assertj-core:3.25.3")
1722
testImplementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.4")
18-
testImplementation("org.junit.platform:junit-platform-console:1.10.1")
1923
}
2024

2125
tasks.shadowJar {
@@ -58,17 +62,43 @@ val testProGuard by tasks.registering(JavaExec::class) {
5862
dependsOn(proguardJar)
5963
notCompatibleWithConfigurationCache("ProGuard")
6064

61-
mainClass.set("org.junit.platform.console.ConsoleLauncher")
65+
mainClass.set("com.withorb.api.proguard.ProGuardCompatibilityTest")
6266
classpath = files(proguardJarPath)
67+
}
68+
69+
val r8JarPath = "${layout.buildDirectory.get()}/libs/${project.name}-${project.version}-r8.jar"
70+
val r8Jar by tasks.registering(JavaExec::class) {
71+
group = "verification"
72+
dependsOn(tasks.shadowJar)
73+
notCompatibleWithConfigurationCache("R8")
74+
75+
mainClass.set("com.android.tools.r8.R8")
76+
classpath = buildscript.configurations["classpath"]
77+
6378
args = listOf(
64-
"--classpath", proguardJarPath,
65-
"--scan-classpath",
66-
"--details", "verbose",
79+
"--release",
80+
"--classfile",
81+
"--output", r8JarPath,
82+
"--lib", System.getProperty("java.home"),
83+
"--pg-conf", "./test.pro",
84+
"--pg-conf", "../orb-kotlin-core/src/main/resources/META-INF/proguard/orb-kotlin-core.pro",
85+
"--pg-map-output", "${layout.buildDirectory.get()}/r8-mapping.txt",
86+
tasks.shadowJar.get().archiveFile.get().asFile.absolutePath,
6787
)
6888
}
6989

90+
val testR8 by tasks.registering(JavaExec::class) {
91+
group = "verification"
92+
dependsOn(r8Jar)
93+
notCompatibleWithConfigurationCache("R8")
94+
95+
mainClass.set("com.withorb.api.proguard.ProGuardCompatibilityTest")
96+
classpath = files(r8JarPath)
97+
}
98+
7099
tasks.test {
71100
dependsOn(testProGuard)
101+
dependsOn(testR8)
72102
// We defer to the tests run via the ProGuard JAR.
73103
enabled = false
74104
}

orb-kotlin-proguard-test/src/test/kotlin/com/withorb/api/proguard/ProGuardCompatibilityTest.kt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,31 @@ import com.withorb.api.models.BillingCycleRelativeDate
1010
import com.withorb.api.models.Discount
1111
import com.withorb.api.models.PercentageDiscount
1212
import com.withorb.api.models.TransformPriceFilter
13+
import kotlin.reflect.full.memberFunctions
14+
import kotlin.reflect.jvm.javaMethod
1315
import org.assertj.core.api.Assertions.assertThat
14-
import org.junit.jupiter.api.BeforeAll
1516
import org.junit.jupiter.api.Test
1617

1718
internal class ProGuardCompatibilityTest {
1819

1920
companion object {
2021

21-
@BeforeAll
2222
@JvmStatic
23-
fun setUp() {
23+
fun main(args: Array<String>) {
2424
// To debug that we're using the right JAR.
2525
val jarPath = this::class.java.getProtectionDomain().codeSource.location
2626
println("JAR being used: $jarPath")
27+
28+
// We have to manually run the test methods instead of using the JUnit runner because it
29+
// seems impossible to get working with R8.
30+
val test = ProGuardCompatibilityTest()
31+
test::class
32+
.memberFunctions
33+
.asSequence()
34+
.filter { function ->
35+
function.javaMethod?.isAnnotationPresent(Test::class.java) == true
36+
}
37+
.forEach { it.call(test) }
2738
}
2839
}
2940

orb-kotlin-proguard-test/test.pro

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@
22
-keep class com.withorb.api.proguard.** { *; }
33

44
# For the testing framework.
5-
-keep class org.junit.** { *; }
5+
-keep class org.junit.** { *; }
6+
7+
# Many warnings don't apply for our testing purposes.
8+
-dontwarn

0 commit comments

Comments
 (0)