From ea3adb06293e2b69d4b31edb149e3dde6b80a482 Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Wed, 29 Mar 2017 20:13:22 +0300 Subject: [PATCH] Implemented resolving the compiler jar using the class loader Added resolving the compiler jar using the class loader urls as the first step with the fallback to the original resolution method. Also helps if the compiler is not present in the classpath dependencies. Issues: #KT-16580 Fixed Changed to getting plugin version from the applied plugin instead of the plugin JAR name. Removed unnecessary working with version of AbstractKotlinPlugin. --- .../KotlinGradlePluginMultiVersionIT.kt | 9 ++++++++ .../kotlinProjectWithBuildSrc/build.gradle | 1 + .../buildSrc/build.gradle | 9 ++++++++ .../src/main/kotlin/Hello.kt | 1 + .../gradle/plugin/KotlinPluginWrapper.kt | 2 +- .../kotlin/gradle/tasks/jarSearchingUtil.kt | 21 +++++++++++++++++-- 6 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinProjectWithBuildSrc/build.gradle create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinProjectWithBuildSrc/buildSrc/build.gradle create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinProjectWithBuildSrc/src/main/kotlin/Hello.kt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginMultiVersionIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginMultiVersionIT.kt index 58c979886d3..a295962ca08 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginMultiVersionIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginMultiVersionIT.kt @@ -59,4 +59,13 @@ class KotlinGradlePluginMultiVersionIT : BaseMultiGradleVersionIT() { assertNotContains("None of the classes needs to be compiled!") } } + + @Test fun testApplyPluginFromBuildSrc() { + val project = Project("kotlinProjectWithBuildSrc", gradleVersion) + project.setupWorkingDir() + File(project.projectDir, "buildSrc/build.gradle").modify { it.replace("\$kotlin_version", KOTLIN_VERSION) } + project.build("build") { + assertSuccessful() + } + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinProjectWithBuildSrc/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinProjectWithBuildSrc/build.gradle new file mode 100644 index 00000000000..770686d110a --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinProjectWithBuildSrc/build.gradle @@ -0,0 +1 @@ +apply plugin: 'kotlin' \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinProjectWithBuildSrc/buildSrc/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinProjectWithBuildSrc/buildSrc/build.gradle new file mode 100644 index 00000000000..9cca5f841bc --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinProjectWithBuildSrc/buildSrc/build.gradle @@ -0,0 +1,9 @@ +repositories { + mavenLocal() +} + +apply plugin: 'java' + +dependencies { + runtime "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinProjectWithBuildSrc/src/main/kotlin/Hello.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinProjectWithBuildSrc/src/main/kotlin/Hello.kt new file mode 100644 index 00000000000..65490fbf75f --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinProjectWithBuildSrc/src/main/kotlin/Hello.kt @@ -0,0 +1 @@ +fun hello() = "Hello" \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt index 779ec8241dc..e04b3cbe97e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt @@ -33,7 +33,7 @@ import javax.inject.Inject abstract class KotlinBasePluginWrapper(protected val fileResolver: FileResolver): Plugin { private val log = Logging.getLogger(this.javaClass) - protected val kotlinPluginVersion = loadKotlinVersionFromResource(log) + val kotlinPluginVersion = loadKotlinVersionFromResource(log) override fun apply(project: Project) { // TODO: consider only set if if daemon or parallel compilation are enabled, though this way it should be safe too diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/jarSearchingUtil.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/jarSearchingUtil.kt index 0bcb8ea23b0..0b1f102cfb0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/jarSearchingUtil.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/jarSearchingUtil.kt @@ -20,7 +20,10 @@ import org.gradle.api.Project import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.ResolvedDependency import org.gradle.api.initialization.dsl.ScriptHandler +import org.jetbrains.kotlin.gradle.plugin.KotlinBasePluginWrapper +import org.jetbrains.kotlin.gradle.plugin.KotlinPlugin import java.io.File +import java.net.URLClassLoader import java.net.URLDecoder import java.nio.charset.Charset import java.util.zip.ZipFile @@ -55,9 +58,23 @@ private fun findJarByClass(klass: Class<*>): File? { } private fun findKotlinCompilerJar(project: Project, compilerClassName: String): File? { - val filesToCheck = findPotentialCompilerJars(project) + val pluginVersion = pluginVersionFromAppliedPlugin(project) + + val filesToCheck = sequenceOf(pluginVersion?.let(::getCompilerFromClassLoader)) + + Sequence { findPotentialCompilerJars(project).iterator() } //call the body only when queried val entryToFind = compilerClassName.replace(".", "/") + ".class" - return filesToCheck.firstOrNull { it.hasEntry(entryToFind) } + return filesToCheck.filterNotNull().firstOrNull { it.hasEntry(entryToFind) } +} + +private fun pluginVersionFromAppliedPlugin(project: Project): String? = + project.plugins.filterIsInstance().firstOrNull()?.kotlinPluginVersion + +private fun getCompilerFromClassLoader(pluginVersion: String): File? { + val urlClassLoader = KotlinPlugin::class.java.classLoader as? URLClassLoader ?: return null + return urlClassLoader.urLs + .firstOrNull { it.toString().endsWith("kotlin-compiler-embeddable-$pluginVersion.jar") } + ?.let { File(it.toURI()) } + ?.takeIf(File::exists) } private fun findPotentialCompilerJars(project: Project): Iterable {