Plugin dependencies loading.

This commit is contained in:
Karlatemp 2020-09-04 20:29:34 +08:00
parent a10e48cc36
commit 68ca9a67e5
No known key found for this signature in database
GPG Key ID: 21FBDDF664FF06F8
2 changed files with 54 additions and 2 deletions

View File

@ -26,6 +26,7 @@ import net.mamoe.mirai.utils.info
import java.io.File
import java.net.URLClassLoader
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentLinkedQueue
internal object JarPluginLoaderImpl :
AbstractFilePluginLoader<JvmPlugin, JvmPluginDescription>(".jar"),
@ -43,7 +44,7 @@ internal object JarPluginLoaderImpl :
override val dataStorage: PluginDataStorage
get() = MiraiConsoleImplementationBridge.dataStorageForJarPluginLoader
internal val classLoaders: MutableList<ClassLoader> = mutableListOf()
internal val classLoaders: ConcurrentLinkedQueue<JvmPluginClassLoader> = ConcurrentLinkedQueue()
@Suppress("EXTENSION_SHADOWED_BY_MEMBER") // doesn't matter
override val JvmPlugin.description: JvmPluginDescription
@ -70,7 +71,7 @@ internal object JarPluginLoaderImpl :
val filePlugins = this.filterNot {
pluginFileToInstanceMap.containsKey(it)
}.associateWith {
URLClassLoader(arrayOf(it.toURI().toURL()), MiraiConsole::class.java.classLoader)
JvmPluginClassLoader(arrayOf(it.toURI().toURL()), MiraiConsole::class.java.classLoader, classLoaders)
}.onEach { (_, classLoader) ->
classLoaders.add(classLoader)
}.asSequence().findAllInstances().onEach { loaded ->

View File

@ -0,0 +1,51 @@
/*
* Copyright 2019-2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*
*/
@file:Suppress("MemberVisibilityCanBePrivate")
package net.mamoe.mirai.console.internal.plugin
import java.net.URL
import java.net.URLClassLoader
import java.util.concurrent.ConcurrentHashMap
internal class JvmPluginClassLoader(
urls: Array<URL>,
parent: ClassLoader?,
val classloaders: Collection<JvmPluginClassLoader>
) : URLClassLoader(urls, parent) {
private val cache = ConcurrentHashMap<String, Class<*>>()
companion object {
init {
ClassLoader.registerAsParallelCapable()
}
}
// private val
override fun findClass(name: String): Class<*> {
return findClass(name, false) ?: throw ClassNotFoundException(name)
}
internal fun findClass(name: String, disableGlobal: Boolean): Class<*>? {
val cachedClass = cache[name]
if (cachedClass != null) return cachedClass
kotlin.runCatching { return super.findClass(name).also { cache[name] = it } }
if (disableGlobal)
return null
classloaders.forEach { otherClassloader ->
if (otherClassloader === this) return@forEach
val otherClass = otherClassloader.findClass(name, true)
if (otherClass != null) return otherClass
}
return null
}
}