Use platform class loader in 'kotlin' runner on JDK 9+

#KT-46312 Fixed
This commit is contained in:
Alexander Udalov
2022-08-04 02:02:42 +02:00
parent 2cb6483e8a
commit 45abea5b0a
4 changed files with 50 additions and 15 deletions
@@ -84,30 +84,24 @@ abstract class AbstractRunner : Runner {
class MainClassRunner(override val className: String) : AbstractRunner() {
override fun createClassLoader(classpath: List<URL>): 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<URL>): 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
}
+7
View File
@@ -0,0 +1,7 @@
package test
import java.sql.Driver
fun main() {
println(Driver::class.java)
}
@@ -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,
)
}
}
@@ -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
}