Fix multiplatform projects communication broken if the plugin is loaded
more than once in different class loaders. Issue #KT-20634 Fixed (cherry picked from commit c65f210)
This commit is contained in:
+37
@@ -84,4 +84,41 @@ class MultiplatformGradleIT : BaseGradleIT() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testSubprojectWithAnotherClassLoader() {
|
||||||
|
with(Project("multiplatformProject", GRADLE_VERSION)) {
|
||||||
|
setupWorkingDir()
|
||||||
|
|
||||||
|
// Make sure there is a plugin applied with the plugins DSL, so that Gradle loads the
|
||||||
|
// plugins separately for the subproject, with a different class loader:
|
||||||
|
File(projectDir, "libJs/build.gradle").modify {
|
||||||
|
"plugins { id 'com.moowork.node' version '1.0.1' }" + "\n" + it
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the root project buildscript dependency, needed for the same purpose:
|
||||||
|
File(projectDir, "build.gradle").modify {
|
||||||
|
it.replace("classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:\$kotlin_version'", "")
|
||||||
|
.apply { assert(!equals(it)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instead, add the dependencies directly to the subprojects buildscripts:
|
||||||
|
listOf("lib", "libJvm", "libJs").forEach { subDirectory ->
|
||||||
|
File(projectDir, "$subDirectory/build.gradle").modify {
|
||||||
|
"""
|
||||||
|
buildscript {
|
||||||
|
repositories { mavenLocal(); jcenter() }
|
||||||
|
dependencies {
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${'$'}kotlin_version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""".trimIndent() + "\n" + it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
build("build") {
|
||||||
|
assertSuccessful()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+9
-3
@@ -95,7 +95,7 @@ open class KotlinPlatformImplementationPluginBase(platformName: String) : Kotlin
|
|||||||
}
|
}
|
||||||
|
|
||||||
commonProject.whenEvaluated {
|
commonProject.whenEvaluated {
|
||||||
if ((!commonProject.plugins.hasPlugin(KotlinPlatformCommonPlugin::class.java))) {
|
if (!commonProject.pluginManager.hasPlugin("kotlin-platform-common")) {
|
||||||
throw GradleException(
|
throw GradleException(
|
||||||
"Platform project $platformProject has an " +
|
"Platform project $platformProject has an " +
|
||||||
"'$EXPECTED_BY_CONFIG_NAME'${if (implementConfigurationIsUsed) "/'$IMPLEMENT_CONFIG_NAME'" else ""} " +
|
"'$EXPECTED_BY_CONFIG_NAME'${if (implementConfigurationIsUsed) "/'$IMPLEMENT_CONFIG_NAME'" else ""} " +
|
||||||
@@ -115,7 +115,14 @@ open class KotlinPlatformImplementationPluginBase(platformName: String) : Kotlin
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected val SourceSet.kotlin: SourceDirectorySet?
|
protected val SourceSet.kotlin: SourceDirectorySet?
|
||||||
get() = ((getConvention("kotlin") ?: getConvention("kotlin2js")) as? KotlinSourceSet)?.kotlin
|
get() {
|
||||||
|
// Access through reflection, because another project's KotlinSourceSet might be loaded
|
||||||
|
// by a different class loader:
|
||||||
|
val convention = (getConvention("kotlin") ?: getConvention("kotlin2js")) ?: return null
|
||||||
|
val kotlinSourceSetIface = convention.javaClass.interfaces.find { it.name == KotlinSourceSet::class.qualifiedName }
|
||||||
|
val getKotlin = kotlinSourceSetIface?.methods?.find { it.name == "getKotlin" } ?: return null
|
||||||
|
return getKotlin(convention) as? SourceDirectorySet
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@@ -128,7 +135,6 @@ open class KotlinPlatformImplementationPluginBase(platformName: String) : Kotlin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open class KotlinPlatformJvmPlugin : KotlinPlatformImplementationPluginBase("jvm") {
|
open class KotlinPlatformJvmPlugin : KotlinPlatformImplementationPluginBase("jvm") {
|
||||||
|
|||||||
Reference in New Issue
Block a user