mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-10 23:35:04 +08:00
Fix plugin's dependencies classes linking; fix #2054
This commit is contained in:
parent
e25e604c79
commit
48c2b04a49
@ -0,0 +1 @@
|
|||||||
|
net.mamoe.consoleit.issue2054:moda:1.0.0
|
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
|
*
|
||||||
|
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
|
*
|
||||||
|
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
package issue2054.modulea
|
||||||
|
|
||||||
|
public object ModuleA {
|
||||||
|
public fun act(b: () -> Unit) {
|
||||||
|
b()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
|
*
|
||||||
|
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
|
*
|
||||||
|
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("UnusedImport")
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
kotlin("jvm")
|
||||||
|
kotlin("plugin.serialization")
|
||||||
|
id("java")
|
||||||
|
}
|
||||||
|
|
||||||
|
version = "0.0.0"
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
explicitApiWarning()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api(project(":mirai-console.integration-test"))
|
||||||
|
api(parent!!.project("module-moda"))
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
net.mamoe.consoleit.issue2054:modb:1.0.0
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
|
*
|
||||||
|
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
|
*
|
||||||
|
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
package issue2054.moduleb
|
||||||
|
|
||||||
|
import issue2054.modulea.ModuleA
|
||||||
|
|
||||||
|
|
||||||
|
public object ModuleB {
|
||||||
|
public val getModuleA: Any get() = ModuleA
|
||||||
|
public fun act(b: () -> Unit) {
|
||||||
|
b()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
|
#
|
||||||
|
# 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
# Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
|
#
|
||||||
|
# https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||||
|
#
|
||||||
|
|
||||||
|
pdepdep2054.PDepDependOnDep
|
@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
|
#
|
||||||
|
# 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
# Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
|
#
|
||||||
|
# https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||||
|
#
|
||||||
|
|
||||||
|
pdepdep2054sec.PDepDependOnDepSec
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
|
*
|
||||||
|
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
|
*
|
||||||
|
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pdepdep2054sec
|
||||||
|
|
||||||
|
import issue2054.modulea.ModuleA
|
||||||
|
import issue2054.moduleb.ModuleB
|
||||||
|
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
|
||||||
|
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
|
||||||
|
import net.mamoe.mirai.utils.info
|
||||||
|
import kotlin.test.assertSame
|
||||||
|
|
||||||
|
public object PDepDependOnDepSec : KotlinPlugin(
|
||||||
|
JvmPluginDescription("net.mamoe.console.itest.plugin-dep-dependon-dep-sec", "0.0.0") {
|
||||||
|
dependsOn("net.mamoe.console.itest.plugin-dep-dependon-dep")
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
override fun onEnable() {
|
||||||
|
jvmPluginClasspath.downloadAndAddToPath(
|
||||||
|
jvmPluginClasspath.pluginIndependentLibrariesClassLoader,
|
||||||
|
listOf("net.mamoe.consoleit.issue2054:modb:1.0.0")
|
||||||
|
)
|
||||||
|
|
||||||
|
assertSame(ModuleA, ModuleB.getModuleA)
|
||||||
|
logger.info { "issue 2054" }
|
||||||
|
|
||||||
|
ModuleB.act { ModuleA.act { logger.info(Throwable("Stack trace")) } }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
|
*
|
||||||
|
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
|
*
|
||||||
|
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pdepdep2054
|
||||||
|
|
||||||
|
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
|
||||||
|
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
|
||||||
|
|
||||||
|
public object PDepDependOnDep : KotlinPlugin(
|
||||||
|
JvmPluginDescription("net.mamoe.console.itest.plugin-dep-dependon-dep", "0.0.0")
|
||||||
|
) {
|
||||||
|
init {
|
||||||
|
jvmPluginClasspath.downloadAndAddToPath(
|
||||||
|
jvmPluginClasspath.pluginSharedLibrariesClassLoader,
|
||||||
|
listOf("net.mamoe.consoleit.issue2054:moda:1.0.0")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -245,6 +245,9 @@ internal class BuiltInJvmPluginLoaderImpl(
|
|||||||
}.mapNotNull { it.javaClass.classLoader.safeCast<JvmPluginClassLoaderN>() }.forEach { dependency ->
|
}.mapNotNull { it.javaClass.classLoader.safeCast<JvmPluginClassLoaderN>() }.forEach { dependency ->
|
||||||
plugin.logger.debug { "Linked dependency: $dependency" }
|
plugin.logger.debug { "Linked dependency: $dependency" }
|
||||||
jvmPluginClassLoaderN.dependencies.add(dependency)
|
jvmPluginClassLoaderN.dependencies.add(dependency)
|
||||||
|
jvmPluginClassLoaderN.pluginSharedCL.dependencies.cast<MutableList<DynLibClassLoader>>().add(
|
||||||
|
dependency.pluginSharedCL
|
||||||
|
)
|
||||||
}
|
}
|
||||||
jvmPluginClassLoaderN.linkPluginLibraries(plugin.logger)
|
jvmPluginClassLoaderN.linkPluginLibraries(plugin.logger)
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ internal class JvmPluginsLoadingCtx(
|
|||||||
|
|
||||||
internal class DynLibClassLoader : URLClassLoader {
|
internal class DynLibClassLoader : URLClassLoader {
|
||||||
private val clName: String?
|
private val clName: String?
|
||||||
|
internal var dependencies: List<DynLibClassLoader> = emptyList()
|
||||||
|
|
||||||
private constructor(parent: ClassLoader?, clName: String?) : super(arrayOf(), parent) {
|
private constructor(parent: ClassLoader?, clName: String?) : super(arrayOf(), parent) {
|
||||||
this.clName = clName
|
this.clName = clName
|
||||||
@ -140,13 +141,22 @@ internal class DynLibClassLoader : URLClassLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun findButNoSystem(name: String): Class<*>? {
|
internal fun findButNoSystem(name: String): Class<*>? = findButNoSystem(name, mutableListOf())
|
||||||
|
private fun findButNoSystem(name: String, track: MutableList<DynLibClassLoader>): Class<*>? {
|
||||||
if (name.startsWith("java.")) return null
|
if (name.startsWith("java.")) return null
|
||||||
|
|
||||||
|
// Skip duplicated searching, for faster speed.
|
||||||
|
if (this in track) return null
|
||||||
|
track.add(this)
|
||||||
|
|
||||||
val pt = this.parent
|
val pt = this.parent
|
||||||
if (pt is DynLibClassLoader) {
|
if (pt is DynLibClassLoader) {
|
||||||
pt.findButNoSystem(name)?.let { return it }
|
pt.findButNoSystem(name, track)?.let { return it }
|
||||||
}
|
}
|
||||||
|
dependencies.forEach { dep ->
|
||||||
|
dep.findButNoSystem(name, track)?.let { return it }
|
||||||
|
}
|
||||||
|
|
||||||
synchronized(getClassLoadingLock(name)) {
|
synchronized(getClassLoadingLock(name)) {
|
||||||
findLoadedClass(name)?.let { return it }
|
findLoadedClass(name)?.let { return it }
|
||||||
try {
|
try {
|
||||||
@ -160,22 +170,10 @@ internal class DynLibClassLoader : URLClassLoader {
|
|||||||
override fun loadClass(name: String, resolve: Boolean): Class<*> {
|
override fun loadClass(name: String, resolve: Boolean): Class<*> {
|
||||||
tryFastOrStrictResolve(name)?.let { return it }
|
tryFastOrStrictResolve(name)?.let { return it }
|
||||||
|
|
||||||
val pt = this.parent
|
findButNoSystem(name)?.let { return it }
|
||||||
val topPt: ClassLoader? = if (pt is DynLibClassLoader) {
|
|
||||||
pt.findButNoSystem(name)?.let { return it }
|
|
||||||
|
|
||||||
generateSequence<ClassLoader>(pt) { it.parent }.firstOrNull { it !is DynLibClassLoader }
|
val topParent = generateSequence<ClassLoader>(this) { it.parent }.firstOrNull { it !is DynLibClassLoader }
|
||||||
} else pt
|
return Class.forName(name, false, topParent)
|
||||||
|
|
||||||
|
|
||||||
synchronized(getClassLoadingLock(name)) {
|
|
||||||
findLoadedClass(name)?.let { return it }
|
|
||||||
try {
|
|
||||||
return findClass(name)
|
|
||||||
} catch (ignored: ClassNotFoundException) {
|
|
||||||
}
|
|
||||||
return Class.forName(name, false, topPt)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,6 +234,7 @@ internal class JvmPluginClassLoaderN : URLClassLoader {
|
|||||||
pluginIndependentCL = DynLibClassLoader.newInstance(
|
pluginIndependentCL = DynLibClassLoader.newInstance(
|
||||||
pluginSharedCL, "IndependentCL{${file.name}}", "${file.name}[private]"
|
pluginSharedCL, "IndependentCL{${file.name}}", "${file.name}[private]"
|
||||||
)
|
)
|
||||||
|
pluginSharedCL.dependencies = mutableListOf()
|
||||||
addURL(file.toURI().toURL())
|
addURL(file.toURI().toURL())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user