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

View File

@ -3,103 +3,31 @@ package net.mamoe.mirai.console.plugins
import java.io.File
import java.net.URLClassLoader
internal class PluginsClassLoader(private val parent: ClassLoader) {
private val pluginLoaders = mutableMapOf<String, PluginClassLoader>()
internal class PluginsClassLoader(private val parent: ClassLoader) {
private var cl : URLClassLoader? = null
/**
* 加载多个插件
*/
fun loadPlugins(pluginsLocation: Map<String, File>) {
for ((key, value) in pluginsLocation) {
pluginLoaders[key] = PluginClassLoader(value, this)
}
cl = URLClassLoader(
pluginsLocation.values.map { it.toURI().toURL() }.toTypedArray(),
parent)
}
/**
* 清除所有插件加载器
*/
fun clear() {
pluginLoaders.values.forEach {
it.close()
}
pluginLoaders.clear()
cl?.close()
}
/**
* 移除单个插件加载
* 加载
*/
fun remove(pluginName: String): Boolean {
pluginLoaders[pluginName]?.close() ?: return false
pluginLoaders.remove(pluginName)
return true
}
fun loadClass(name: String): Class<*>? {
var c: Class<*>? = null
// 循环插件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
fun loadPluginMainClass(name: String) : Class<*>{
return cl?.loadClass(name) ?: error("PluginsClassLoader has not yet run the loadPlugins func.")
}
}
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
}
}
}