Open TheFloodDragon opened 6 months ago
RuntimeEnv:
// 在非隔离模式下检查 Kotlin 环境
if (!PrimitiveSettings.IS_ISOLATED_MODE) {
// 加载 Kotlin 环境
if (!KOTLIN_VERSION.equals("null") && !TabooLib.isKotlinEnvironment()) {
ENV.loadDependency("org.jetbrains.kotlin:kotlin-stdlib:" + KOTLIN_VERSION, rel);
}
// 加载 Kotlin Coroutines 环境
if (!KOTLIN_COROUTINES_VERSION.equals("null") && !TabooLib.isKotlinCoroutinesEnvironment()) {
ENV.loadDependency("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:" + KOTLIN_COROUTINES_VERSION, false, rel);
}
}
其中仅仅在非隔离模式下加载Kotlin环境,开启隔离模式后貌似就无法使用Kotlin,导致报错
我操,小作文
一个问题
RuntimeEnv:
// 在非隔离模式下检查 Kotlin 环境 if (!PrimitiveSettings.IS_ISOLATED_MODE) { // 加载 Kotlin 环境 if (!KOTLIN_VERSION.equals("null") && !TabooLib.isKotlinEnvironment()) { ENV.loadDependency("org.jetbrains.kotlin:kotlin-stdlib:" + KOTLIN_VERSION, rel); } // 加载 Kotlin Coroutines 环境 if (!KOTLIN_COROUTINES_VERSION.equals("null") && !TabooLib.isKotlinCoroutinesEnvironment()) { ENV.loadDependency("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:" + KOTLIN_COROUTINES_VERSION, false, rel); } }
其中仅仅在非隔离模式下加载Kotlin环境,开启隔离模式后貌似就无法使用Kotlin,导致报错
坏黑的逆天逻辑
使用沙盒本就是为了避免版本冲突的问题,如果还能直接访问岂不是变成弱智
除非像 nms proxy 那种操作,实现一种针对其他 tb 插件的访问模式
使用沙盒本就是为了避免版本冲突的问题,如果还能直接访问岂不是变成弱智
这个就是ClassLoaderProvider
的用处了,对包名进行过滤处理,仅通过插件包下的类,毕竟不同版本的库总是要区分的
实现一种针对其他 tb 插件的访问模式
上述方式其实都是。
无论是通过反射,CompatibleClassLoader托管其他Taboolib的IsolatedClassLoader,或是暴力修改parent(破坏逻辑)从而选择性开放部分类
前言
沙盒限制
以上内容节选自相关链接[1]:注意事项,由Sunshine_wzy等人写的
在一些特殊场景下,开发者不得不使用沙盒模式,但同时其限制又成了一个困扰点
虽然说可以通过SPI开放部分类,但其实现(相关链接[1]:优秀实践)却并不简单
这也就意味着,其所能提供的API终是有限的
因此,衍生出这样一个话题:如何“摆脱”隔离,自由地访问和使用“沙盒中的类” (不使用SPI)
论方法
目前,在我的理解范围之内,有以下几种方法:
通过IsolatedClassLoader获取类并反射调用
指直接通过IsolatedClassLoader#loadClass函数获取目标类
然后通过反射执行调用其方法、获取和修改其字段等等操作
如:
IsolatedClassLoader.loadClass("taboolib.common.PrimitiveLoader").getProperty("TABOOLIB_GROUP", isStatic=true)
面对小范围的沙盒类使用,此方法是可行的,也是较优选择
实现自定义类加载器,
适应性提供类托管其他IsolatedClassLoder原理: 通过自定义类加载器,根据ClassLoaderProvider(也可以是ClassProvider)获取想要获得的类
其主要包括: 由ClassLoaderProvider通过全限类定名提供类加载器,由CompatibleClassLoader通过selfLoad加载特定类(受委托的类),来使用ClassLoaderProvider所能提供的类
限制: 还是那样,受委托的类可以调用“沙盒中的类”的什么什么,却无法向外部提供“沙盒中的类”
因此,对于事件的注册,请使用目标插件的
InternalEvent
好处: 简化反射流程,可以直接调用沙盒类的东西,可以根据需求决定能访问到的类
类加载器示例:
使用方法:
侵入式破坏加载顺序 (设想)
在观察Bukkit、Velocity、Bungee的PluginClassLoader后,发现一个规律: 在加载类时,都会首先使用
super.loadClass(name, resolve)
, 走“双亲委派”那一套?所以,是不是可以在这做文章,修改
parent
,破坏其加载顺序?其他
待补充。。。
相关链接
Document#IsolatedClassLoader
Bukkit#PluginClassLoader
Velocity#PluginClassLoader
Bungee#PluginClassLoader
ps: 我菜,各位大佬有什么想法尽管提!