revert PluginsClassLoader to fix 'suspended issue'

This commit is contained in:
Sincky 2020-04-07 13:52:07 +08:00 committed by Him188
parent b08546b5aa
commit c9f0195f8e
2 changed files with 13 additions and 85 deletions

View File

@ -212,9 +212,9 @@ object PluginManager {
try { try {
val pluginClass = try{ val pluginClass = try{
pluginsClassLoader.loadClass(description.basePath) pluginsClassLoader.loadPluginMainClass(description.basePath)
} catch (e: ClassNotFoundException) { } catch (e: ClassNotFoundException) {
pluginsClassLoader.loadClass("${description.basePath}Kt") pluginsClassLoader.loadPluginMainClass("${description.basePath}Kt")
} }
return try { return try {
@ -297,7 +297,7 @@ object PluginManager {
plugin.disable(exception) plugin.disable(exception)
nameToPluginBaseMap.remove(plugin.pluginName) nameToPluginBaseMap.remove(plugin.pluginName)
pluginDescriptions.remove(plugin.pluginName) pluginDescriptions.remove(plugin.pluginName)
pluginsClassLoader.remove(plugin.pluginName) //pluginsClassLoader.remove(plugin.pluginName)
pluginsSequence.remove(plugin) pluginsSequence.remove(plugin)
} }

View File

@ -3,103 +3,31 @@ package net.mamoe.mirai.console.plugins
import java.io.File import java.io.File
import java.net.URLClassLoader import java.net.URLClassLoader
internal class PluginsClassLoader(private val parent: ClassLoader) { internal class PluginsClassLoader(private val parent: ClassLoader) {
private val pluginLoaders = mutableMapOf<String, PluginClassLoader>()
private var cl : URLClassLoader? = null
/** /**
* 加载多个插件 * 加载多个插件
*/ */
fun loadPlugins(pluginsLocation: Map<String, File>) { fun loadPlugins(pluginsLocation: Map<String, File>) {
for ((key, value) in pluginsLocation) { cl = URLClassLoader(
pluginLoaders[key] = PluginClassLoader(value, this) pluginsLocation.values.map { it.toURI().toURL() }.toTypedArray(),
} parent)
} }
/** /**
* 清除所有插件加载器 * 清除所有插件加载器
*/ */
fun clear() { fun clear() {
pluginLoaders.values.forEach { cl?.close()
it.close()
}
pluginLoaders.clear()
} }
/** /**
* 移除单个插件加载 * 加载
*/ */
fun remove(pluginName: String): Boolean {
pluginLoaders[pluginName]?.close() ?: return false
pluginLoaders.remove(pluginName)
return true
}
fun loadClass(name: String): Class<*>? { fun loadPluginMainClass(name: String) : Class<*>{
var c: Class<*>? = null return cl?.loadClass(name) ?: error("PluginsClassLoader has not yet run the loadPlugins func.")
// 循环插件classloader loadClass
pluginLoaders.values.forEach {
try{
c = it.loadClass(name)
return@forEach
}catch (e : ClassNotFoundException){/*nothing*/}
}
if(c == null){
throw ClassNotFoundException("PluginsClassLoader can't load this class:${name}")
}
return c
}
fun loadDependClass(name: String): Class<*>? {
var c: Class<*>? = null
// 依赖问题先交给MiraiClassLoader来处理
try {
c = parent.loadClass(name)
}catch (e : ClassNotFoundException){/*nothing*/}
// 然后再交给插件的classloader来加载依赖
if (c == null) {
pluginLoaders.values.forEach {
try {
c = it.loadDependClass(name)
return@forEach
}catch (e : ClassNotFoundException){/*nothing*/}
}
}
return c
} }
} }
internal class PluginClassLoader(files: File,private val parent: PluginsClassLoader) :
URLClassLoader(arrayOf((files.toURI().toURL()))) {
override fun loadClass(name: String): Class<*>? {
synchronized(getClassLoadingLock(name)) {
// 看缓存中是否加载过此类
var c = findLoadedClass(name)
if (c == null) {
c = try {
// 父类去加载本插件的依赖
parent.loadDependClass(name)
} catch (e: ClassNotFoundException) {
// 自己加载本插件按理说只有本插件的ClassName会到达这里
this.findClass(name)//ClassNotFoundException or java.lang.LinkageError
}
}
return c
}
}
fun loadDependClass(name: String): Class<*>? {
synchronized(getClassLoadingLock(name)) {
var c = findLoadedClass(name)
if (c == null) {
// 加载依赖,没有则丢出异常
c = this.findClass(name) // ClassNotFoundException
}
return c
}
}
}