ForgelinSetup 预载钩子
基本信息
| 属性 | 值 |
|---|---|
| 所属 | Forgelin(modid forgelin) |
| 类型 | IFMLCallHook 实现 |
| 源码 | preloader/ForgelinSetup.kt:8 |
| 调用方 | ForgelinPlugin.getSetupClass()(ForgelinPlugin.kt:22) |
作用
在 FML 的类加载早期,用真实 ClassLoader 显式加载一次 KotlinAdapter。
目的是让 Kotlin 运行时(以及被 shadow 打包进来的 kotlinx-coroutines)
在任何 mod 的类被加载之前完成初始化,避免 NoClassDefFoundError。
override fun injectData(data: Map<String?, Any?>?) {
val loader = data?.get("classLoader") as ClassLoader?
try {
loader?.loadClass("net.shadowfacts.forgelin.KotlinAdapter")
} catch (e: ClassNotFoundException) {
// this should never happen
throw RuntimeException("Couldn't find Forgelin language adapter, this shouldn't be happening", e)
}
}
(ForgelinSetup.kt:9-17)
call() 返回 null(行 19-22),即注册到 List<FMLCallHook> 后不执行任何后置动作,
本类的全部作用就是 injectData 里那一行 loadClass。
与 FML 数据类的关系
injectData 从传入的 Map 里取 "classLoader" 键,类型断言为 ClassLoader?。
该 Map 由 FML 构造,键名与 ForgelinPlugin 收到的
injectData 是同一份。源码用 as(非 as?)强转,若该键缺失会抛
NullPointerException 而非给出可读错误。
已知源码问题
loader为null时静默跳过:使用了安全调用loader?.loadClass(...), 若data为null或键不存在,预载会被无声跳过,类初始化时机退回默认行为。 与ForgelinAutomaticEventSubscriber.kt:28的静默早退是同一类问题。RuntimeException包装掩盖根因:注释写 “this should never happen”, 抛出后 FML 只会看到一条 Forgelin 自己的异常,原始ClassNotFoundException作为 cause 挂在下面。@Throws(Exception::class)标注在call()上(行 19),但该方法实际不抛任何异常, 属冗余声明。
相关条目
- ForgelinPlugin 加载入口 - 指定本类为 setup 类
- KotlinAdapter - 被预载的目标类