mirror of
https://github.com/mamoe/mirai.git
synced 2025-04-25 13:03:35 +08:00
Fix DynLibClassLoader class resolving logic
This commit is contained in:
parent
237320317e
commit
72d248f1e6
mirai-console/backend
integration-test
src
testers/plugin-resolve-self-dependencies-over-console-ones/src
mirai-console/src/internal/plugin
@ -39,6 +39,19 @@ public fun File.assertNotExists() {
|
||||
fail { "Except ${this.absolutePath} not exists but this file exists in disk" }
|
||||
}
|
||||
}
|
||||
|
||||
public fun assertClassSame(expected: Class<*>?, actually: Class<*>?) {
|
||||
fun vt(c: Class<*>?): String {
|
||||
if (c == null) return "<null>"
|
||||
return "$c from ${c.classLoader}"
|
||||
}
|
||||
if (expected === actually) return
|
||||
fail {
|
||||
"Class not same:\n" +
|
||||
"Class excepted: ${vt(expected)}\n" +
|
||||
"Class actually: ${vt(actually)}"
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region JVM Utils
|
||||
@ -48,7 +61,7 @@ public val vmClassfileVersion: Int = runCatching {
|
||||
classobj.version
|
||||
}.recoverCatching {
|
||||
val ccl = object : ClassLoader(null) {
|
||||
fun canLoad(ver: Int) : Boolean{
|
||||
fun canLoad(ver: Int): Boolean {
|
||||
val klass = ClassWriter(ClassWriter.COMPUTE_MAXS)
|
||||
val cname =
|
||||
"net/mamoe/console/integrationtest/vtest/C${ver}_${System.currentTimeMillis()}_${UUID.randomUUID()}"
|
||||
|
@ -12,6 +12,7 @@ package pluginresolveselfdepoverconsoleones
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.java.*
|
||||
import io.ktor.client.plugins.resources.*
|
||||
import net.mamoe.console.integrationtest.assertClassSame
|
||||
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
|
||||
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
|
||||
import net.mamoe.mirai.utils.info
|
||||
@ -27,5 +28,7 @@ public class PluginResolveSelfDependenciesOverConsoleOnes :
|
||||
install(Resources)
|
||||
}.toString()
|
||||
}
|
||||
val hcC = Class.forName("io.ktor.client.HttpClient")
|
||||
assertClassSame(hcC, jvmPluginClassLoaderAccess.pluginIndependentLibrariesClassLoader.loadClass(hcC.name))
|
||||
}
|
||||
}
|
@ -79,6 +79,22 @@ internal class DynLibClassLoader : URLClassLoader {
|
||||
else -> DynLibClassLoader(parent, clName)
|
||||
}
|
||||
}
|
||||
|
||||
fun tryFastOrStrictResolve(name: String): Class<*>? {
|
||||
if (name.startsWith("java.")) return Class.forName(name, false, JavaSystemPlatformClassLoader)
|
||||
|
||||
// All mirai-core hard-linked should use same version to avoid errors (ClassCastException).
|
||||
if (name.startsWith("io.netty") || name in AllDependenciesClassesHolder.allclasses) {
|
||||
return AllDependenciesClassesHolder.appClassLoader.loadClass(name)
|
||||
}
|
||||
if (name.startsWith("net.mamoe.mirai.")) { // Avoid plugin classing cheating
|
||||
try {
|
||||
return AllDependenciesClassesHolder.appClassLoader.loadClass(name)
|
||||
} catch (ignored: ClassNotFoundException) {
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
internal fun loadClassInThisClassLoader(name: String): Class<*>? {
|
||||
@ -142,7 +158,8 @@ internal class DynLibClassLoader : URLClassLoader {
|
||||
}
|
||||
|
||||
override fun loadClass(name: String, resolve: Boolean): Class<*> {
|
||||
if (name.startsWith("java.")) return Class.forName(name, false, JavaSystemPlatformClassLoader)
|
||||
tryFastOrStrictResolve(name)?.let { return it }
|
||||
|
||||
val pt = this.parent
|
||||
val topPt: ClassLoader? = if (pt is DynLibClassLoader) {
|
||||
pt.findButNoSystem(name)?.let { return it }
|
||||
@ -331,16 +348,8 @@ internal class JvmPluginClassLoaderN : URLClassLoader {
|
||||
override fun loadClass(name: String, resolve: Boolean): Class<*> = loadClass(name)
|
||||
|
||||
override fun loadClass(name: String): Class<*> {
|
||||
if (name.startsWith("java.")) return Class.forName(name, false, JavaSystemPlatformClassLoader)
|
||||
if (name.startsWith("io.netty") || name in AllDependenciesClassesHolder.allclasses) {
|
||||
return AllDependenciesClassesHolder.appClassLoader.loadClass(name)
|
||||
}
|
||||
if (name.startsWith("net.mamoe.mirai.")) { // Avoid plugin classing cheating
|
||||
try {
|
||||
return AllDependenciesClassesHolder.appClassLoader.loadClass(name)
|
||||
} catch (ignored: ClassNotFoundException) {
|
||||
}
|
||||
}
|
||||
DynLibClassLoader.tryFastOrStrictResolve(name)?.let { return it }
|
||||
|
||||
sharedLibrariesLogger.loadClassInThisClassLoader(name)?.let { return it }
|
||||
|
||||
// Search dependencies first
|
||||
|
Loading…
Reference in New Issue
Block a user