lwjgl3ify

lwjgl3ify

1.6k Downloads

Incompatibility with OptiFine D6

makamys opened this issue ยท 4 comments

commented

I'm not sure if there's any way to fix this from LWJGL3ify's side, but I figured it would be worth reporting.

OptiFine D6 obtains a ZipFile reference to its own jar file roughly like this:

URLClassLoader ucl = (URLClassLoader)OptiFineClassTransformer.class.getClassLoader();
URL[] urls = ucl.getURLs();
// ...
ZipFile self = new ZipFile(new File(urls[i]));

An exception happens on the first line since in new versions of Java, AppClassLoader is no longer a subclass of URLClassLoader.

[15:00:19] [main/INFO] [LaunchWrapper/]: Calling tweak class optifine.OptiFineForgeTweaker
[15:00:19] [main/INFO] [STDOUT/]: [optifine.OptiFineForgeTweaker:dbg:56]: OptiFineForgeTweaker: acceptOptions
[15:00:19] [main/INFO] [STDOUT/]: [optifine.OptiFineForgeTweaker:dbg:56]: OptiFineForgeTweaker: injectIntoClassLoader
[15:00:19] [main/INFO] [STDERR/]: [java.lang.Throwable$WrappedPrintStream:println:785]: java.lang.ClassCastException: class jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to class java.net.URLClassLoader (jdk.internal.loader.ClassLoaders$AppClassLoader and java.net.URLClassLoader are in module java.base of loader 'bootstrap')
[15:00:19] [main/INFO] [STDERR/]: [java.lang.Throwable$WrappedPrintStream:println:785]: 	at optifine.OptiFineClassTransformer.<init>(OptiFineClassTransformer.java:40)
[15:00:19] [main/INFO] [STDERR/]: [java.lang.Throwable$WrappedPrintStream:println:785]: 	at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:67)
[15:00:19] [main/INFO] [STDERR/]: [java.lang.Throwable$WrappedPrintStream:println:785]: 	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
[15:00:19] [main/INFO] [STDERR/]: [java.lang.Throwable$WrappedPrintStream:println:785]: 	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:484)
[15:00:19] [main/INFO] [STDERR/]: [java.lang.Throwable$WrappedPrintStream:println:785]: 	at net.minecraft.launchwrapper.LaunchClassLoader.registerTransformer(LaunchClassLoader.java:94)
[15:00:19] [main/INFO] [STDERR/]: [java.lang.Throwable$WrappedPrintStream:println:785]: 	at optifine.OptiFineForgeTweaker.injectIntoClassLoader(OptiFineForgeTweaker.java:38)
[15:00:19] [main/INFO] [STDERR/]: [java.lang.Throwable$WrappedPrintStream:println:785]: 	at net.minecraft.launchwrapper.Launch.launch(Launch.java:145)
[15:00:19] [main/INFO] [STDERR/]: [java.lang.Throwable$WrappedPrintStream:println:785]: 	at net.minecraft.launchwrapper.Launch.main(Launch.java:29)
[15:00:19] [main/INFO] [STDERR/]: [java.lang.Throwable$WrappedPrintStream:println:785]: 	at org.prismlauncher.launcher.impl.StandardLauncher.launch(StandardLauncher.java:88)
[15:00:19] [main/INFO] [STDERR/]: [java.lang.Throwable$WrappedPrintStream:println:785]: 	at org.prismlauncher.EntryPoint.listen(EntryPoint.java:126)
[15:00:19] [main/INFO] [STDERR/]: [java.lang.Throwable$WrappedPrintStream:println:785]: 	at org.prismlauncher.EntryPoint.main(EntryPoint.java:71)
[15:00:19] [main/INFO] [STDOUT/]: [optifine.OptiFineClassTransformer:dbg:266]: *** Can not find the OptiFine JAR in the classpath ***
[15:00:19] [main/INFO] [STDOUT/]: [optifine.OptiFineClassTransformer:dbg:266]: *** OptiFine will not be loaded! ***

OptiFine E7 doesn't have this problem, since it instead uses OptiFineClassTransformer.class.getProtectionDomain().getCodeSource().getLocation() to get the URL. The reason D6 is relevant is because it has been found to give better performance than E7 in some cases.

commented

Fixed in alpha 6.

commented

With FastCraft 1.23 + OptiFine D6, disabling stbiTextureStiching is required because the flashing issue happens otherwise. I'll make a PR that updates the auto-detection logic in a moment.

commented

I have released a tiny mod that hacks Java 9 compat into OptiFine D6, so a workaround exists now.
https://github.com/makamys/OptiFine3ify

Ponderings on merging this into LWJGL3ify

This hack cannot be cleanly added to LWJGL3ify (at least the mod) since it requires precise ordering between coremod initialization events. Here are the events we're working with:

1a. OptiFine tweaker gets loaded -> optifine gets added as a class loader exception
1b. Mixin tweaker gets loaded -> FML plugins of mixins run
2. OptiFine tweaker gets called -> OptiFineTransformer gets loaded
3. Mixin tweaker gets called -> PREINIT phase starts -> mixin config plugins run

The order between 1a and 1b is dependent on jar name, so it cannot be guaranteed. The order between 2 and 3 is decided by the TweakOrder of the tweakers, which is -1000 in OptiFine's case, and always 0 in practice in the case of the MixinTweaker.

Transforming OptiFineClassTransformer is difficult because its package gets added as a class loader exclusion during the construction of the OptiFine tweaker. If we wish to transform it using a class transformer, we must remove the exclusion between 1a and 2. OptiFine3ify can do this easily since it can choose whatever TweakOrder it wants. But LWJGL3ify cannot, and as such has no way to guarantee whether its code runs before or after 1a.

There does exist an order-agnostic solution: if we're before 1a, replace LaunchClassLoader#classLoaderExceptions with a proxy object that refuses to add optifine to the underlying set. But I assume that's too hacky for the project's standards.

commented

oh cool so we can use Fastcraft 1.2.3 and Optifine D6 ontop with newest java version :)