[console] Add LegacyCompatibilityLayerClassLoader; Load ktor 1.6.8 as fallback; fix #2297

This commit is contained in:
Karlatemp 2022-10-29 23:26:24 +08:00
parent a47a8e1c2a
commit d47221fa35
No known key found for this signature in database
GPG Key ID: BA173CA2B9956C59
3 changed files with 82 additions and 23 deletions

View File

@ -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" } }

View File

@ -41,6 +41,7 @@ Class resolving:
*/
internal class JvmPluginsLoadingCtx(
val consoleClassLoader: ClassLoader, // plugin system -> mirai-console classloader WRAPPER
val sharedLibrariesLoader: DynLibClassLoader,
val pluginClassLoaders: MutableList<JvmPluginClassLoaderN>,
val downloader: JvmPluginDependencyDownloader,
@ -51,17 +52,18 @@ internal class JvmPluginsLoadingCtx(
}
}
internal class DynLibClassLoader : URLClassLoader {
private val clName: String?
internal var dependencies: List<DynLibClassLoader> = emptyList()
private constructor(parent: ClassLoader?, clName: String?) : super(arrayOf(), parent) {
this.clName = clName
}
internal open class DynamicClasspathClassLoader : URLClassLoader {
internal constructor(urls: Array<URL>, 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<URL>, 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<DynLibClassLoader> = 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)
}
}

View File

@ -253,7 +253,7 @@ internal class JvmPluginDependencyDownloader(
logger.debug { "Remote server: " + config.repoLoc }
}
fun resolveDependencies(deps: Collection<String>, vararg filters: DependencyFilter): DependencyResult {
fun resolveDependencies(deps: Iterable<String>, vararg filters: DependencyFilter): DependencyResult {
val dependencies: MutableList<Dependency> = ArrayList()
for (library in deps) {