From 35c08e8b16abcb513aed6fcd8e0c62cbaaee3213 Mon Sep 17 00:00:00 2001 From: Karlatemp <karlatemp@vip.qq.com> Date: Sat, 23 Apr 2022 17:13:58 +0800 Subject: [PATCH] Link mirai-core in console IT, fix non-hard-linked dependencies resolving --- .../backend/integration-test/build.gradle.kts | 1 + .../internal/plugin/JvmPluginClassLoader.kt | 38 ++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/mirai-console/backend/integration-test/build.gradle.kts b/mirai-console/backend/integration-test/build.gradle.kts index a0577f49f..76f09da0d 100644 --- a/mirai-console/backend/integration-test/build.gradle.kts +++ b/mirai-console/backend/integration-test/build.gradle.kts @@ -27,6 +27,7 @@ kotlin { dependencies { api(project(":mirai-core-api")) api(project(":mirai-core-utils")) + testRuntimeOnly(project(":mirai-core")) api(project(":mirai-console-compiler-annotations")) api(project(":mirai-console")) api(project(":mirai-console-terminal")) diff --git a/mirai-console/backend/mirai-console/src/internal/plugin/JvmPluginClassLoader.kt b/mirai-console/backend/mirai-console/src/internal/plugin/JvmPluginClassLoader.kt index 7d0fbe70e..f37e1e2a7 100644 --- a/mirai-console/backend/mirai-console/src/internal/plugin/JvmPluginClassLoader.kt +++ b/mirai-console/backend/mirai-console/src/internal/plugin/JvmPluginClassLoader.kt @@ -104,6 +104,40 @@ internal class DynLibClassLoader( } } + internal fun findButNoSystem(name: String): Class<*>? { + val pt = this.parent + if (pt is DynLibClassLoader) { + pt.findButNoSystem(name)?.let { return it } + } + synchronized(getClassLoadingLock(name)) { + findLoadedClass(name)?.let { return it } + try { + findClass(name)?.let { return it } + } catch (ignored: ClassNotFoundException) { + } + } + return null + } + + override fun loadClass(name: String, resolve: Boolean): Class<*> { + if (name.startsWith("java.")) return Class.forName(name, false, null) + val pt = this.parent + val topPt: ClassLoader? = if (pt is DynLibClassLoader) { + pt.findButNoSystem(name)?.let { return it } + + generateSequence<ClassLoader>(pt) { it.parent }.firstOrNull { it !is DynLibClassLoader } + } else pt + + + synchronized(getClassLoadingLock(name)) { + findLoadedClass(name)?.let { return it } + try { + return findClass(name) + } catch (ignored: ClassNotFoundException) { + } + return Class.forName(name, false, topPt) + } + } } @Suppress("JoinDeclarationAndAssignment") @@ -134,6 +168,7 @@ internal class JvmPluginClassLoaderN : URLClassLoader { init0() } + @Suppress("Since15") private constructor(file: File, ctx: JvmPluginsLoadingCtx) : super( file.name, arrayOf(), ctx.sharedLibrariesLoader @@ -223,7 +258,7 @@ internal class JvmPluginClassLoaderN : URLClassLoader { } else { pluginIndependentCL.addLib(lib) } - logger.debug { "Linked $artifact $linkType" } + logger.debug { "Linked $artifact $linkType <${if (shared) pluginSharedCL else pluginIndependentCL}>" } } } @@ -268,6 +303,7 @@ internal class JvmPluginClassLoaderN : URLClassLoader { override fun loadClass(name: String, resolve: Boolean): Class<*> = loadClass(name) override fun loadClass(name: String): Class<*> { + if (name.startsWith("java.")) return Class.forName(name, false, null) if (name.startsWith("io.netty") || name in AllDependenciesClassesHolder.allclasses) { return AllDependenciesClassesHolder.appClassLoader.loadClass(name) }