From 45abea5b0af91929d300592ece1099a4096ba780 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 4 Aug 2022 02:02:42 +0200 Subject: [PATCH] Use platform class loader in 'kotlin' runner on JDK 9+ #KT-46312 Fixed --- .../org/jetbrains/kotlin/runner/runners.kt | 29 ++++++++++--------- compiler/testData/launcher/jdkModuleUsage.kt | 7 +++++ .../kotlin/cli/LauncherScriptTest.kt | 27 +++++++++++++++++ .../plugin/JvmCliScriptEvaluationExtension.kt | 2 +- 4 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 compiler/testData/launcher/jdkModuleUsage.kt diff --git a/compiler/cli/cli-runner/src/org/jetbrains/kotlin/runner/runners.kt b/compiler/cli/cli-runner/src/org/jetbrains/kotlin/runner/runners.kt index 0f106c1a9a0..0f99f49a749 100644 --- a/compiler/cli/cli-runner/src/org/jetbrains/kotlin/runner/runners.kt +++ b/compiler/cli/cli-runner/src/org/jetbrains/kotlin/runner/runners.kt @@ -84,30 +84,24 @@ abstract class AbstractRunner : Runner { class MainClassRunner(override val className: String) : AbstractRunner() { override fun createClassLoader(classpath: List): ClassLoader = - URLClassLoader(classpath.toTypedArray(), null) + URLClassLoader(classpath.toTypedArray(), getPlatformClassLoader()) } class JarRunner(private val path: String) : AbstractRunner() { override val className: String = - try { - val jar = JarFile(path) - try { - jar.manifest.mainAttributes.getValue(Attributes.Name.MAIN_CLASS) - } - finally { - jar.close() - } + try { + JarFile(path).use { jar -> + jar.manifest.mainAttributes.getValue(Attributes.Name.MAIN_CLASS) } - catch (e: IOException) { - throw RunnerException("could not read manifest from " + path + ": " + e.message) - } - ?: throw RunnerException("no Main-Class entry found in manifest in $path") + } catch (e: IOException) { + throw RunnerException("could not read manifest from " + path + ": " + e.message) + } ?: throw RunnerException("no Main-Class entry found in manifest in $path") override fun createClassLoader(classpath: List): ClassLoader { // 'kotlin *.jar' ignores the passed classpath as 'java -jar' does // TODO: warn on non-empty classpath? - return URLClassLoader(arrayOf(File(path).toURI().toURL()), null) + return URLClassLoader(arrayOf(File(path).toURI().toURL()), getPlatformClassLoader()) } } @@ -176,3 +170,10 @@ class ExpressionRunner(private val code: String) : RunnerWithCompiler() { runCompiler(compilerClasspath, compilerArgs) } } + +private fun getPlatformClassLoader(): ClassLoader? = + try { + ClassLoader::class.java.getDeclaredMethod("getPlatformClassLoader")?.invoke(null) as? ClassLoader? + } catch (_: Exception) { + null + } diff --git a/compiler/testData/launcher/jdkModuleUsage.kt b/compiler/testData/launcher/jdkModuleUsage.kt new file mode 100644 index 00000000000..292d45ecb53 --- /dev/null +++ b/compiler/testData/launcher/jdkModuleUsage.kt @@ -0,0 +1,7 @@ +package test + +import java.sql.Driver + +fun main() { + println(Driver::class.java) +} diff --git a/compiler/tests/org/jetbrains/kotlin/cli/LauncherScriptTest.kt b/compiler/tests/org/jetbrains/kotlin/cli/LauncherScriptTest.kt index f8dc0170dcc..a3a3816da70 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/LauncherScriptTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/cli/LauncherScriptTest.kt @@ -444,4 +444,31 @@ println(42) workDirectory = subDir ) } + + fun testKotlinUseJdkModuleFromMainClass() { + val jdk11 = mapOf("JAVA_HOME" to KtTestUtil.getJdk11Home().absolutePath) + runProcess( + "kotlinc", "$testDataDirectory/jdkModuleUsage.kt", "-d", tmpdir.path, + environment = jdk11, + ) + runProcess( + "kotlin", "-cp", tmpdir.path, "test.JdkModuleUsageKt", + expectedStdout = "interface java.sql.Driver\n", + environment = jdk11, + ) + } + + fun testKotlinUseJdkModuleFromJar() { + val jdk11 = mapOf("JAVA_HOME" to KtTestUtil.getJdk11Home().absolutePath) + val output = tmpdir.resolve("out.jar") + runProcess( + "kotlinc", "$testDataDirectory/jdkModuleUsage.kt", "-d", output.path, + environment = jdk11, + ) + runProcess( + "kotlin", output.path, + expectedStdout = "interface java.sql.Driver\n", + environment = jdk11, + ) + } } diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JvmCliScriptEvaluationExtension.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JvmCliScriptEvaluationExtension.kt index e0c069859c3..51068bfc8f6 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JvmCliScriptEvaluationExtension.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JvmCliScriptEvaluationExtension.kt @@ -51,7 +51,7 @@ class JvmCliScriptEvaluationExtension : AbstractScriptEvaluationExtension() { private fun getPlatformClassLoader(): ClassLoader? = try { - ClassLoader::class.java.getDeclaredMethod("getPlatformClassLoader")?.invoke(null)?.let { it as? ClassLoader } + ClassLoader::class.java.getDeclaredMethod("getPlatformClassLoader")?.invoke(null) as? ClassLoader? } catch (_: Exception) { null }