fix(compat): load warashi tracker via context classloader
上一版用 ModContainer.getClassLoader() 编译失败(该 API 不存在)。 改为:线程上下文 classloader + Class.forName 默认加载 双重兜底, 均失败则桥降级 no-op。不依赖任何具体 loader API。
This commit is contained in:
1 parent
cc0cbe1679
commit
e358289931
1 file changed
+35
-16
@@ -1,7 +1,6 @@
|
||||
package dev.modzuozhi.core.compat;
|
||||
|
||||
import dev.modzuozhi.ModZuozhi;
|
||||
import net.neoforged.fml.loading.FMLLoader;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
@@ -17,11 +16,11 @@ import java.lang.invoke.MethodType;
|
||||
* <p>
|
||||
* <b>软依赖</b>:DR 不编译期依赖 warashi。仅在 warashi 加载时,通过 {@link MethodHandle}
|
||||
* 反射调用其 {@code PerfWorkTracker.enterScope(Object)} / {@code exitScope()}。未加载则全 no-op。
|
||||
* <p>
|
||||
* 通过 {@code FMLLoader} 检测(与 {@code DimensionalRipperMixinPlugin} 检测 C2ME 同一模式),
|
||||
* 不引入运行时类加载风险。
|
||||
*/
|
||||
public final class WarashiScopeBridge {
|
||||
private static final String TRACKER_CLASS =
|
||||
"com.moepus.serverwarashi.common.modules.performance.sampling.PerfWorkTracker";
|
||||
|
||||
private static final MethodHandle ENTER_SCOPE;
|
||||
private static final MethodHandle EXIT_SCOPE;
|
||||
private static final boolean ACTIVE;
|
||||
@@ -31,19 +30,19 @@ public final class WarashiScopeBridge {
|
||||
MethodHandle exit = null;
|
||||
boolean active = false;
|
||||
try {
|
||||
var loadingMods = FMLLoader.getLoadingModList();
|
||||
boolean warashiLoaded = loadingMods != null
|
||||
&& loadingMods.getModFileById("serverwarashi") != null;
|
||||
boolean warashiLoaded = net.neoforged.fml.ModList.get()
|
||||
.getModContainerById("serverwarashi").isPresent();
|
||||
if (warashiLoaded) {
|
||||
Class<?> tracker = Class.forName(
|
||||
"com.moepus.serverwarashi.common.modules.performance.sampling.PerfWorkTracker");
|
||||
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
|
||||
enter = lookup.findStatic(tracker, "enterScope",
|
||||
MethodType.methodType(void.class, Object.class));
|
||||
exit = lookup.findStatic(tracker, "exitScope",
|
||||
MethodType.methodType(void.class));
|
||||
active = true;
|
||||
ModZuozhi.LOGGER.info("[DimThread] ServerWarashi 检测到,已挂接采样作用域桥");
|
||||
Class<?> tracker = loadTrackerClass();
|
||||
if (tracker != null) {
|
||||
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
|
||||
enter = lookup.findStatic(tracker, "enterScope",
|
||||
MethodType.methodType(void.class, Object.class));
|
||||
exit = lookup.findStatic(tracker, "exitScope",
|
||||
MethodType.methodType(void.class));
|
||||
active = true;
|
||||
ModZuozhi.LOGGER.info("[DimThread] ServerWarashi 检测到,已挂接采样作用域桥");
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// warashi 未加载 / 签名不匹配:静默降级为 no-op,绝不影响 DR 主流程。
|
||||
@@ -60,6 +59,26 @@ public final class WarashiScopeBridge {
|
||||
private WarashiScopeBridge() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载 warashi 的 {@code PerfWorkTracker} 类。
|
||||
* <p>
|
||||
* 依次尝试:线程上下文 classloader(FML 运行期通常是能看全部 mod 的 TransformingClassLoader),
|
||||
* 以及不带显式 loader 的默认加载。均失败返回 null(桥降级为 no-op)。
|
||||
*/
|
||||
private static Class<?> loadTrackerClass() {
|
||||
try {
|
||||
return Class.forName(TRACKER_CLASS, false,
|
||||
Thread.currentThread().getContextClassLoader());
|
||||
} catch (Throwable ignored) {
|
||||
// fallthrough
|
||||
}
|
||||
try {
|
||||
return Class.forName(TRACKER_CLASS);
|
||||
} catch (Throwable ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** 是否成功挂接 warashi。 */
|
||||
public static boolean isActive() {
|
||||
return ACTIVE;
|
||||
|
||||
Reference in new issue
Block a user