Class LegacyTweakerClassLoaderBridge

java.lang.Object
com.hloader.launch.LegacyTweakerClassLoaderBridge
All Implemented Interfaces:
ClassFileTransformer

public final class LegacyTweakerClassLoaderBridge extends Object implements ClassFileTransformer
Pre-1.6 Minecraft loads its game classes through a custom, child-first classloader (net.minecraft.launchwrapper.LaunchClassLoader) that only delegates to its parent (the real system classloader) for package prefixes it's explicitly told to. Vanilla LaunchWrapper predates Sponge Mixin and has no such exclusion for it, so once Minecraft.class - which our mixin transformer has woven references to Mixin's runtime API into - actually runs, resolving a type like org.spongepowered.asm.mixin.injection.callback.CallbackInfo throws ClassNotFoundException: that class lives in hloader's own jar, reachable from the system classloader (appended there via -javaagent), but LaunchClassLoader never asks its parent for it.

This piggybacks on the same ClassFileTransformer hook Instrumentation already gives every classloader's defineClass calls: the first time we see one that looks like a LaunchClassLoader (matched by class name only, so this works across Minecraft versions and any fork of LaunchWrapper, not just the exact vanilla 1.5 build), we reflectively call its public addClassLoaderExclusion(String) for the package prefixes hloader itself needs resolved through the parent.

org.lwjgl. needs the same treatment for an unrelated reason: without it, LaunchClassLoader defines its own separate copy of LWJGL's classes, distinct from whichever classloader's copy the native library's JNI bindings actually got resolved against when System.loadLibrary first ran. A native callback into "the wrong" copy of a class is exactly the kind of classloader-identity mismatch that crashes the JVM natively (segfault inside jni_CallVoidMethod) rather than throwing a catchable Java exception - this is why pre-1.6 (LaunchWrapper-based) versions could crash creating their window even when later, non-LaunchWrapper versions using the exact same LWJGL native library work fine.

  • Constructor Details

    • LegacyTweakerClassLoaderBridge

      public LegacyTweakerClassLoaderBridge()
  • Method Details