Skip to content

Commit 0039be6

Browse files
committed
Fix binary incompatibility with Android Gradle plugin 3.2.0-alpha06
Remove a non-reflective usage of the ResourceSet class, which has been moved to a different package between versions. Access it through reflection instead. This is a workaround. We can introduce a proper fix once we have a public API in the Android plugin. The test case that could detect the compatibility issue is `testAndroidExtensionsManyVariants` (it uses experimental Android extensions), but we did not run it with 3.2.0-alpha6. This commit adds a test class with the same tests for 3.2.0-alpha6. Issue #KT-23192 Fixed
1 parent 3a7a34c commit 0039be6

File tree

3 files changed

+26
-11
lines changed

3 files changed

+26
-11
lines changed

libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,15 @@ import java.io.File
1313
class KotlinAndroidGradleIT : AbstractKotlinAndroidGradleTests(gradleVersion = GradleVersionRequired.AtLeast("3.4"), androidGradlePluginVersion = "2.3.0")
1414
class KotlinAndroidWithJackGradleIT : AbstractKotlinAndroidWithJackGradleTests(androidGradlePluginVersion = "2.3.+")
1515

16-
class KotlinAndroid30GradleIT : AbstractKotlinAndroidGradleTests(gradleVersion = GradleVersionRequired.AtLeast("4.1"), androidGradlePluginVersion = "3.0.0-beta1") {
16+
// TODO If we there is a way to fetch the latest Android plugin version, test against the latest version
17+
class KotlinAndroid32GradleIT : KotlinAndroid3GradleIT(GradleVersionRequired.AtLeast("4.5"), "3.2.0-alpha06")
18+
19+
class KotlinAndroid30GradleIT : KotlinAndroid3GradleIT(GradleVersionRequired.AtLeast("4.1"), "3.0.0")
20+
21+
abstract class KotlinAndroid3GradleIT(
22+
gradleVersionRequired: GradleVersionRequired,
23+
androidGradlePluginVersion: String
24+
) : AbstractKotlinAndroidGradleTests(gradleVersionRequired, androidGradlePluginVersion) {
1725

1826
@Test
1927
fun testApplyWithFeaturePlugin() {
@@ -314,5 +322,4 @@ abstract class AbstractKotlinAndroidWithJackGradleTests(
314322
assertContains("Kotlin Gradle plugin does not support the deprecated Jack toolchain")
315323
}
316324
}
317-
}
318-
325+
}

libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidProject/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ buildscript {
1313
allprojects {
1414
repositories {
1515
mavenLocal()
16-
mavenCentral()
16+
jcenter()
1717
maven { url 'https://maven.google.com' }
1818
}
1919
}

libraries/tools/kotlin-gradle-plugin/src/agp25/kotlin/org/jetbrains/kotlin/gradle/plugin/android/Android25ProjectHandler.kt

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import com.android.build.gradle.*
44
import com.android.build.gradle.api.*
55
import com.android.build.gradle.tasks.MergeResources
66
import com.android.builder.model.SourceProvider
7-
import com.android.ide.common.res2.ResourceSet
87
import org.gradle.api.Project
98
import org.gradle.api.file.FileCollection
109
import org.gradle.api.tasks.compile.AbstractCompile
@@ -120,7 +119,7 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools
120119
}
121120

122121
override fun getResDirectories(variantData: BaseVariant): List<File> {
123-
return variantData.mergeResources?.computeResourceSetList0()?.flatMap { it.sourceFiles } ?: emptyList()
122+
return variantData.mergeResources?.computeResourceSetList0() ?: emptyList()
124123
}
125124

126125
private inner class KaptVariant(variantData: BaseVariant) : KaptVariantData<BaseVariant>(variantData) {
@@ -143,17 +142,26 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools
143142
}
144143
}
145144

146-
//TODO once the Android plugin reaches its 3.0.0 release, consider compiling against it (remove the reflective call)
147-
//TODO this is a private API for now
148-
private fun MergeResources.computeResourceSetList0(): List<ResourceSet>? {
145+
//TODO A public API is expected for this purpose. Once it is available, use the public API
146+
private fun MergeResources.computeResourceSetList0(): List<File>? {
149147
val computeResourceSetListMethod = MergeResources::class.java.declaredMethods
150148
.firstOrNull { it.name == "computeResourceSetList" && it.parameterCount == 0 } ?: return null
151149

152150
val oldIsAccessible = computeResourceSetListMethod.isAccessible
153151
try {
154152
computeResourceSetListMethod.isAccessible = true
155-
@Suppress("UNCHECKED_CAST")
156-
return computeResourceSetListMethod.invoke(this) as? List<ResourceSet>
153+
154+
val resourceSets = computeResourceSetListMethod.invoke(this) as? Iterable<*>
155+
156+
return resourceSets
157+
?.mapNotNull { resourceSet ->
158+
val getSourceFiles = resourceSet?.javaClass?.methods?.find { it.name == "getSourceFiles" && it.parameterCount == 0 }
159+
val files = getSourceFiles?.invoke(resourceSet)
160+
@Suppress("UNCHECKED_CAST")
161+
files as? Iterable<File>
162+
}
163+
?.flatten()
164+
157165
} finally {
158166
computeResourceSetListMethod.isAccessible = oldIsAccessible
159167
}

0 commit comments

Comments
 (0)