From d47221fa358b314b82b2a5d6a2c6eb8bbd0c8863 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Sat, 29 Oct 2022 23:26:24 +0800 Subject: [PATCH] [console] Add `LegacyCompatibilityLayerClassLoader`; Load ktor 1.6.8 as fallback; fix #2297 --- .../plugin/BuiltInJvmPluginLoaderImpl.kt | 28 ++++++- .../internal/plugin/JvmPluginClassLoader.kt | 75 +++++++++++++------ .../plugin/JvmPluginDependencyDownload.kt | 2 +- 3 files changed, 82 insertions(+), 23 deletions(-) diff --git a/mirai-console/backend/mirai-console/src/internal/plugin/BuiltInJvmPluginLoaderImpl.kt b/mirai-console/backend/mirai-console/src/internal/plugin/BuiltInJvmPluginLoaderImpl.kt index 9f90f8623..0ca7583bc 100644 --- a/mirai-console/backend/mirai-console/src/internal/plugin/BuiltInJvmPluginLoaderImpl.kt +++ b/mirai-console/backend/mirai-console/src/internal/plugin/BuiltInJvmPluginLoaderImpl.kt @@ -75,14 +75,40 @@ internal class BuiltInJvmPluginLoaderImpl( internal val jvmPluginLoadingCtx: JvmPluginsLoadingCtx by lazy { + val legacyCompatibilityLayerClassLoader = LegacyCompatibilityLayerClassLoader.newInstance( + BuiltInJvmPluginLoaderImpl::class.java.classLoader, + ) + val classLoader = DynLibClassLoader.newInstance( - BuiltInJvmPluginLoaderImpl::class.java.classLoader, "GlobalShared", "global-shared" + legacyCompatibilityLayerClassLoader, "GlobalShared", "global-shared" ) val ctx = JvmPluginsLoadingCtx( + legacyCompatibilityLayerClassLoader, classLoader, mutableListOf(), JvmPluginDependencyDownloader(logger), ) + logger.debug { "Downloading legacy compatibility modules....." } + ctx.downloader.resolveDependencies( + sequenceOf( + "client-core", + "client-core-jvm", + "client-okhttp", + "utils", + "utils-jvm", + ).map { "io.ktor:ktor-$it:1.6.8" }.asIterable() + ).let { rsp -> + rsp.artifactResults.forEach { + legacyCompatibilityLayerClassLoader.addLib(it.artifact.file) + } + if (logger.isVerboseEnabled) { + logger.verbose("Legacy compatibility modules:") + rsp.artifactResults.forEach { art -> + logger.verbose(" `- ${art.artifact} -> ${art.artifact.file}") + } + } + } + logger.verbose { "Plugin shared libraries: " + PluginManager.pluginSharedLibrariesFolder } PluginManager.pluginSharedLibrariesFolder.listFiles()?.asSequence().orEmpty() .onEach { logger.debug { "Peek $it in shared libraries" } } 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 f219b0a31..df7baa6cc 100644 --- a/mirai-console/backend/mirai-console/src/internal/plugin/JvmPluginClassLoader.kt +++ b/mirai-console/backend/mirai-console/src/internal/plugin/JvmPluginClassLoader.kt @@ -41,6 +41,7 @@ Class resolving: */ internal class JvmPluginsLoadingCtx( + val consoleClassLoader: ClassLoader, // plugin system -> mirai-console classloader WRAPPER val sharedLibrariesLoader: DynLibClassLoader, val pluginClassLoaders: MutableList, val downloader: JvmPluginDependencyDownloader, @@ -51,17 +52,18 @@ internal class JvmPluginsLoadingCtx( } } -internal class DynLibClassLoader : URLClassLoader { - private val clName: String? - internal var dependencies: List = emptyList() - - private constructor(parent: ClassLoader?, clName: String?) : super(arrayOf(), parent) { - this.clName = clName - } +internal open class DynamicClasspathClassLoader : URLClassLoader { + internal constructor(urls: Array, parent: ClassLoader?) : super(urls, parent) @Suppress("Since15") - private constructor(parent: ClassLoader?, clName: String?, vmName: String?) : super(vmName, arrayOf(), parent) { - this.clName = clName + internal constructor(urls: Array, parent: ClassLoader?, vmName: String?) : super(vmName, urls, parent) + + internal fun addLib(url: URL) { + addURL(url) + } + + internal fun addLib(file: File) { + addURL(file.toURI().toURL()) } @@ -72,7 +74,47 @@ internal class DynLibClassLoader : URLClassLoader { ClassLoader.registerAsParallelCapable() java9 = kotlin.runCatching { Class.forName("java.lang.Module") }.isSuccess } + } +} +internal class LegacyCompatibilityLayerClassLoader : DynamicClasspathClassLoader { + private constructor(parent: ClassLoader?) : super(arrayOf(), parent) + private constructor(parent: ClassLoader?, vmName: String?) : super(arrayOf(), parent, vmName) + + override fun toString(): String { + return "LegacyCompatibilityLayerClassLoader@" + hashCode() + } + + companion object { + init { + ClassLoader.registerAsParallelCapable() + } + + fun newInstance(parent: ClassLoader?): LegacyCompatibilityLayerClassLoader { + return if (java9) { + LegacyCompatibilityLayerClassLoader(parent, "legacy-compatibility-layer") + } else { + LegacyCompatibilityLayerClassLoader(parent) + } + } + } +} + + +internal class DynLibClassLoader : DynamicClasspathClassLoader { + private val clName: String? + internal var dependencies: List = emptyList() + + private constructor(parent: ClassLoader?, clName: String?) : super(arrayOf(), parent) { + this.clName = clName + } + + private constructor(parent: ClassLoader?, clName: String?, vmName: String?) : super(arrayOf(), parent, vmName) { + this.clName = clName + } + + + companion object { fun newInstance(parent: ClassLoader?, clName: String?, vmName: String?): DynLibClassLoader { return when { java9 -> DynLibClassLoader(parent, clName, vmName) @@ -87,7 +129,7 @@ internal class DynLibClassLoader : URLClassLoader { if (name in AllDependenciesClassesHolder.allclasses) { return AllDependenciesClassesHolder.appClassLoader.loadClass(name) } - if (name.startsWith("net.mamoe.mirai.")) { // Avoid plugin classing cheating + if (name.startsWith("net.mamoe.mirai.") || name.startsWith("kotlin.") || name.startsWith("kotlinx.")) { // Avoid plugin classing cheating try { return AllDependenciesClassesHolder.appClassLoader.loadClass(name) } catch (ignored: ClassNotFoundException) { @@ -112,14 +154,6 @@ internal class DynLibClassLoader : URLClassLoader { return null } - internal fun addLib(url: URL) { - addURL(url) - } - - internal fun addLib(file: File) { - addURL(file.toURI().toURL()) - } - override fun toString(): String { clName?.let { return "DynLibClassLoader{$it}" } return "DynLibClassLoader@" + hashCode() @@ -180,7 +214,6 @@ internal class DynLibClassLoader : URLClassLoader { } } -@Suppress("JoinDeclarationAndAssignment") internal class JvmPluginClassLoaderN : URLClassLoader { val openaccess: JvmPluginClasspath = OpenAccess() val file: File @@ -335,7 +368,7 @@ internal class JvmPluginClassLoaderN : URLClassLoader { fun newLoader(file: File, ctx: JvmPluginsLoadingCtx): JvmPluginClassLoaderN { return when { - DynLibClassLoader.java9 -> JvmPluginClassLoaderN(file, ctx) + DynamicClasspathClassLoader.java9 -> JvmPluginClassLoaderN(file, ctx) else -> JvmPluginClassLoaderN(file, ctx, Unit) } } @@ -399,7 +432,7 @@ internal class JvmPluginClassLoaderN : URLClassLoader { } } } - return AllDependenciesClassesHolder.appClassLoader.loadClass(name) + return ctx.consoleClassLoader.loadClass(name) } } diff --git a/mirai-console/backend/mirai-console/src/internal/plugin/JvmPluginDependencyDownload.kt b/mirai-console/backend/mirai-console/src/internal/plugin/JvmPluginDependencyDownload.kt index 55cfadfe8..c504d7888 100644 --- a/mirai-console/backend/mirai-console/src/internal/plugin/JvmPluginDependencyDownload.kt +++ b/mirai-console/backend/mirai-console/src/internal/plugin/JvmPluginDependencyDownload.kt @@ -253,7 +253,7 @@ internal class JvmPluginDependencyDownloader( logger.debug { "Remote server: " + config.repoLoc } } - fun resolveDependencies(deps: Collection, vararg filters: DependencyFilter): DependencyResult { + fun resolveDependencies(deps: Iterable, vararg filters: DependencyFilter): DependencyResult { val dependencies: MutableList = ArrayList() for (library in deps) {