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.
This commit is contained in:
Sergey Igushkin
2017-03-29 20:13:22 +03:00
parent bda59e58d5
commit ea3adb0629
6 changed files with 40 additions and 3 deletions

View File

@@ -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()
}
}
}

View File

@@ -0,0 +1,9 @@
repositories {
mavenLocal()
}
apply plugin: 'java'
dependencies {
runtime "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}

View File

@@ -33,7 +33,7 @@ import javax.inject.Inject
abstract class KotlinBasePluginWrapper(protected val fileResolver: FileResolver): Plugin<Project> {
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

View File

@@ -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<KotlinBasePluginWrapper>().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<File> {