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
This commit is contained in:
+10
-3
@@ -13,7 +13,15 @@ import java.io.File
|
||||
class KotlinAndroidGradleIT : AbstractKotlinAndroidGradleTests(gradleVersion = GradleVersionRequired.AtLeast("3.4"), androidGradlePluginVersion = "2.3.0")
|
||||
class KotlinAndroidWithJackGradleIT : AbstractKotlinAndroidWithJackGradleTests(androidGradlePluginVersion = "2.3.+")
|
||||
|
||||
class KotlinAndroid30GradleIT : AbstractKotlinAndroidGradleTests(gradleVersion = GradleVersionRequired.AtLeast("4.1"), androidGradlePluginVersion = "3.0.0-beta1") {
|
||||
// TODO If we there is a way to fetch the latest Android plugin version, test against the latest version
|
||||
class KotlinAndroid32GradleIT : KotlinAndroid3GradleIT(GradleVersionRequired.AtLeast("4.5"), "3.2.0-alpha06")
|
||||
|
||||
class KotlinAndroid30GradleIT : KotlinAndroid3GradleIT(GradleVersionRequired.AtLeast("4.1"), "3.0.0")
|
||||
|
||||
abstract class KotlinAndroid3GradleIT(
|
||||
gradleVersionRequired: GradleVersionRequired,
|
||||
androidGradlePluginVersion: String
|
||||
) : AbstractKotlinAndroidGradleTests(gradleVersionRequired, androidGradlePluginVersion) {
|
||||
|
||||
@Test
|
||||
fun testApplyWithFeaturePlugin() {
|
||||
@@ -314,5 +322,4 @@ abstract class AbstractKotlinAndroidWithJackGradleTests(
|
||||
assertContains("Kotlin Gradle plugin does not support the deprecated Jack toolchain")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -13,7 +13,7 @@ buildscript {
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
maven { url 'https://maven.google.com' }
|
||||
}
|
||||
}
|
||||
+15
-7
@@ -4,7 +4,6 @@ import com.android.build.gradle.*
|
||||
import com.android.build.gradle.api.*
|
||||
import com.android.build.gradle.tasks.MergeResources
|
||||
import com.android.builder.model.SourceProvider
|
||||
import com.android.ide.common.res2.ResourceSet
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.tasks.compile.AbstractCompile
|
||||
@@ -120,7 +119,7 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools
|
||||
}
|
||||
|
||||
override fun getResDirectories(variantData: BaseVariant): List<File> {
|
||||
return variantData.mergeResources?.computeResourceSetList0()?.flatMap { it.sourceFiles } ?: emptyList()
|
||||
return variantData.mergeResources?.computeResourceSetList0() ?: emptyList()
|
||||
}
|
||||
|
||||
private inner class KaptVariant(variantData: BaseVariant) : KaptVariantData<BaseVariant>(variantData) {
|
||||
@@ -143,17 +142,26 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools
|
||||
}
|
||||
}
|
||||
|
||||
//TODO once the Android plugin reaches its 3.0.0 release, consider compiling against it (remove the reflective call)
|
||||
//TODO this is a private API for now
|
||||
private fun MergeResources.computeResourceSetList0(): List<ResourceSet>? {
|
||||
//TODO A public API is expected for this purpose. Once it is available, use the public API
|
||||
private fun MergeResources.computeResourceSetList0(): List<File>? {
|
||||
val computeResourceSetListMethod = MergeResources::class.java.declaredMethods
|
||||
.firstOrNull { it.name == "computeResourceSetList" && it.parameterCount == 0 } ?: return null
|
||||
|
||||
val oldIsAccessible = computeResourceSetListMethod.isAccessible
|
||||
try {
|
||||
computeResourceSetListMethod.isAccessible = true
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return computeResourceSetListMethod.invoke(this) as? List<ResourceSet>
|
||||
|
||||
val resourceSets = computeResourceSetListMethod.invoke(this) as? Iterable<*>
|
||||
|
||||
return resourceSets
|
||||
?.mapNotNull { resourceSet ->
|
||||
val getSourceFiles = resourceSet?.javaClass?.methods?.find { it.name == "getSourceFiles" && it.parameterCount == 0 }
|
||||
val files = getSourceFiles?.invoke(resourceSet)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
files as? Iterable<File>
|
||||
}
|
||||
?.flatten()
|
||||
|
||||
} finally {
|
||||
computeResourceSetListMethod.isAccessible = oldIsAccessible
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user