diff --git a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/util/jvmClasspathUtil.kt b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/util/jvmClasspathUtil.kt index b86e3f8ea30..2bda3ddcb85 100644 --- a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/util/jvmClasspathUtil.kt +++ b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/util/jvmClasspathUtil.kt @@ -231,11 +231,7 @@ private fun allRelatedClassLoaders(clsLoader: ClassLoader, visited: MutableSet + val arrayOfClassLoaders = getParentClassLoaders(clsLoader) // TODO: PluginClassLoader uses filtering (mustBeLoadedByPlatform), consider using the same logic, if possible // (untill proper compiling from classloader instead of classpath is implemented) arrayOfClassLoaders.asSequence().flatMap { allRelatedClassLoaders(it, visited) } + clsLoader @@ -244,6 +240,38 @@ private fun allRelatedClassLoaders(clsLoader: ClassLoader, visited: MutableSet { + return try { + getParentsForNewClassLoader(clsLoader) + } catch (exception: NoSuchMethodException) { + try { + getParentsForOldClassLoader(clsLoader) + } catch (exception: NoSuchFieldException) { + // Possibly idea sources and kotlin compiler had diverged + emptyArray() + } + } +} + +@Throws(NoSuchFieldException::class) +private fun getParentsForOldClassLoader(clsLoader: ClassLoader): Array { + // Correct way of getting parents in com.intellij.ide.plugins.cl.PluginClassLoader from IDEA 202 and earlier + val field = clsLoader.javaClass.getDeclaredField("myParents") // com.intellij.ide.plugins.cl.PluginClassLoader + field.isAccessible = true + + @Suppress("UNCHECKED_CAST") + return field.get(clsLoader) as Array +} + +@Throws(NoSuchMethodException::class) +private fun getParentsForNewClassLoader(clsLoader: ClassLoader): Array { + // Correct way of getting parents in com.intellij.ide.plugins.cl.PluginClassLoader from IDEA 203+ + val method = clsLoader.javaClass.getDeclaredMethod("getAllParents") + method.isAccessible = true + + @Suppress("UNCHECKED_CAST") + return method.invoke(clsLoader) as Array +} internal fun List.takeIfContainsAll(vararg keyNames: String): List? = takeIf { classpath ->