Crucible icon indicating copy to clipboard operation
Crucible copied to clipboard

Rfb support and new JUL logging

Open gravit0 opened this issue 1 year ago • 18 comments

This PR fixes bugs related to the old version of ASM in mods such as https://github.com/CrucibleMC/Crucible/issues/148 Instead of launchwrapper, https://github.com/GTNewHorizons/RetroFuturaBootstrap is used which provides transformers that fix this and other problems. About JUL RFB breaks hacks used by Crucible to implement logging of plugins and mods. These hacks were removed, and a simplified version of the log4j-jul library was written instead. The log4j-jul library itself has a minimum version of 2.1 and is not compatible with log4j 2.0-beta9. Updating to the latest log4j is complicated by the project structure About SystemClassLoader RFB supports two launch options - with the argument -Djava.system.class.loader=com.gtnewhorizons.retrofuturabootstrap.RfbSystemClassLoader and with the argument -Drfb.skipClassLoaderCheck=true. I don't know which option will be better for Crucible, I didn't notice any difference in behavior during testing. This change may be break something. Requires thorough testing!

gravit0 avatar Jul 26 '24 12:07 gravit0

It would be nice to get rfb transformers working for plugins. I might need some help with that.

gravit0 avatar Jul 26 '24 12:07 gravit0

Plugin transforming is quite a special case, since you would have to delegate plugin classes to launchwrapper (or rfb in this case) but not define them in the lw/rfb classloader. My proposal would be enumerating transformers/plugins manually and having a config of "safe" transformers that can interact with plugins, then call it directly

juanmuscaria avatar Jul 26 '24 14:07 juanmuscaria

Plugin transforming is quite a special case, since you would have to delegate plugin classes to launchwrapper (or rfb in this case) but not define them in the lw/rfb classloader. My proposal would be enumerating transformers/plugins manually and having a config of "safe" transformers that can interact with plugins, then call it directly

I found method https://github.com/GTNewHorizons/RetroFuturaBootstrap/blob/c948dae9fd90c1db88385915c328dfd51971a294/src/main/java/com/gtnewhorizons/retrofuturabootstrap/URLClassLoaderWithUtilities.java#L37 that can be helpful. This method not define class itself, public and can be invoked from PluginClassLoader. Example use from LaunchClassLoader here: https://github.com/GTNewHorizons/RetroFuturaBootstrap/blob/c948dae9fd90c1db88385915c328dfd51971a294/src/main/java/net/minecraft/launchwrapper/LaunchClassLoader.java#L313 I dont know what context need for plugins. It looks easy

gravit0 avatar Jul 26 '24 15:07 gravit0

An alternative option is to use rfb to load plugins directly without PluginClassLoader (the plugin must be ready for this). Unfortunately, such plugins will not be able to interact with others from PluginClassLoader

gravit0 avatar Jul 26 '24 15:07 gravit0

I dont know what context need for plugins. We would need to grab https://github.com/GTNewHorizons/RetroFuturaBootstrap/blob/c948dae9fd90c1db88385915c328dfd51971a294/src/main/java/net/minecraft/launchwrapper/LaunchClassLoader.java#L68 somehow to decide the context, or keep our own transformer exclusion, or both.

About that method, seems like it only invokes rfb transformers while skipping normal lw transformers, which can be good and bad? Rfb transformers would be less common and would not cause as many issues as normal transformers, so less manual labor. But how should mixins be handled?

I'm open to more opinions on how plugin transformation should be handled at all.

juanmuscaria avatar Jul 26 '24 15:07 juanmuscaria

rfb transformers seem safe and are required to work on new versions of Java. We can make options for using rfb and regular transformers the same way remapping is configured now. We can use the runTransformers method via reflection, or if we really need it, create an issue to the authors of RFB. I don't know what exactly is required for mixins to work (maybe some kind of registration of the mod in the system that is not performed in the case of plugins). We are unlikely to encounter a situation where we need to load a class from the exclusion list

gravit0 avatar Jul 26 '24 15:07 gravit0

Enabling rfb and lw transformers did not break the plugins I tested. However, plugins like NBT API and PowerNBT do not work correctly in both staging and rfb-support (this PR) branches. The problem is that Class.forName returns ClassNotFound if the requested name differs from the name of the received class. This problem persists on both Java 17+ and Java 8.

gravit0 avatar Jul 28 '24 16:07 gravit0

That issue in specific was caused by including unimixin, not sure why, but it breaks reflection on vanilla classes due to reflection trying to find unmapped classes.

juanmuscaria avatar Jul 28 '24 16:07 juanmuscaria

That issue in specific was caused by including unimixin, not sure why, but it breaks reflection on vanilla classes due to reflection trying to find unmapped classes.

I not using unimixins while testing.

gravit0 avatar Jul 28 '24 16:07 gravit0

Replace Class.forName to classloader.loadClass works for my test plugin. May be need apply this fix to all plugins by asm transformer?

gravit0 avatar Jul 28 '24 16:07 gravit0

I tested this PR with GTNH 5.6.1 and popular plugins

  1. Small problem with console: small visual bugs with display command
  2. WorldGuard/WorldEdit not compatibility with CoFH (for mods who fix this) lw transformer (but lw transformers for plugins are disabled by default)
  3. Rfb transformers seems fully safe

Plugins (16): CoreProtect, Chatty, LuckPerms, MultiWorld, WorldEdit, Essentials, EssentialsProtect, EssentialsChat, EssentialsAntiBuild, ClearLag, WorldBorder, TestPlugin, EssentialsSpawn, WorldGuard, Multiverse-Core, Crucible_Server

Can you review this PR?

gravit0 avatar Aug 11 '24 16:08 gravit0

Small problem with console: small visual bugs with display command

The logger hack was supposed to fix that by handing over logger control to bukkit console handler

juanmuscaria avatar Aug 12 '24 16:08 juanmuscaria

I wonder if it would be possible to be able to switch between rfb and lw with a simple option toggle, it would require changing crucible bootstrapping a bit though, so something for me to do later.

juanmuscaria avatar Aug 12 '24 16:08 juanmuscaria

The logger hack was supposed to fix that by handing over logger control to bukkit console handler

I try fix this without return logger hack

I wonder if it would be possible to be able to switch between rfb and lw with a simple option toggle, it would require changing crucible bootstrapping a bit though, so something for me to do later.

Probably a bad idea. Rfb contains modified lw classes

gravit0 avatar Aug 12 '24 19:08 gravit0

Probably a bad idea. Rfb contains modified lw classes

With a modified bootstrapping, it either loads crucible lw or rfb, so it would not have any conflict.

juanmuscaria avatar Aug 13 '24 15:08 juanmuscaria

I am testing this pull-request to check for the compats of these changes. My modpack cannot start with these changes. I got this crash from EnderIOAddons after changing from latest-staging to your build:

[CrashReport from EnderIOAddons]

CrashReport

java.lang.NullPointerException: Cannot invoke "net.minecraft.item.ItemStack.func_77973_b()" because "info.loenwind.enderioaddons.recipe.Recipes.capBankCreative" is null
	at Launch//info.loenwind.enderioaddons.plant.EioaGrowthRequirement.<init>(EioaGrowthRequirement.java:34)
	at Launch//info.loenwind.enderioaddons.plant.EioaCropPlant.<init>(EioaCropPlant.java:40)
	at Launch//info.loenwind.enderioaddons.machine.afarm.TileAfarm.registerPlants(TileAfarm.java:138)
	at Launch//info.loenwind.enderioaddons.machine.afarm.AgriDetector.registerPlants(AgriDetector.java:35)
	at Launch//info.loenwind.enderioaddons.proxy.ClientAndServerProxy.init(ClientAndServerProxy.java:66)
	at Launch//info.loenwind.enderioaddons.EnderIOAddons.init(EnderIOAddons.java:80)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at Launch//cpw.mods.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:532)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at Launch//com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
	at Launch//com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
	at Launch//com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
	at Launch//com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
	at Launch//com.google.common.eventbus.EventBus.post(EventBus.java:275)
	at Launch//cpw.mods.fml.common.LoadController.sendEventToModContainer(LoadController.java:212)
	at Launch//cpw.mods.fml.common.LoadController.propogateStateMessage(LoadController.java:190)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at Launch//com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
	at Launch//com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
	at Launch//com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
	at Launch//com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
	at Launch//com.google.common.eventbus.EventBus.post(EventBus.java:275)
	at Launch//cpw.mods.fml.common.LoadController.distributeStateMessage(LoadController.java:119)
	at Launch//cpw.mods.fml.common.Loader.initializeMods(Loader.java:739)
	at Launch//cpw.mods.fml.server.FMLServerHandler.finishServerLoading(FMLServerHandler.java:97)
	at Launch//cpw.mods.fml.common.FMLCommonHandler.onServerStarted(FMLCommonHandler.java:323)
	at Launch//net.minecraft.server.dedicated.DedicatedServer.func_71197_b(DedicatedServer.java:270)
	at Launch//net.minecraft.server.MinecraftServer.run(MinecraftServer.java:644)
	at java.base/java.lang.Thread.run(Thread.java:1583)

Seems to be a problem on a mixin over ItemStack. Maybe the change of loading order of mixins caused that.

Anyway, EnderIoAddons is not the most stable mod in the World, so maybe is something specific with him that can be fixed on the mod itself. But is already something to keep in mind.

~~For the plugins, you said something about WorldGuard and Cofh, i was not able to reproduce the bug you said exist when these two are together, for my modpack the WorldGuard is working. Can you clarify that a little bit~~ oh, its only with lw transformer turned true '-'

EverNife avatar Oct 21 '24 20:10 EverNife

Well, without enabling the lwTransformer everything seems fine. (tecnically is meanted to be enabled for specific plugins so whatever)

Gonna try to fix the compatibility with the EnderIOAddons.

EverNife avatar Oct 21 '24 20:10 EverNife

The logging behavior does not exactly match the logging behavior in staging. You can help to fix the remaining issues

lwTransformers may not be safe for plugins, so they are not enabled by default

gravit0 avatar Oct 21 '24 23:10 gravit0

Tested with latest changes, my modpack still crashes (still enderioaddons only)

[CrashReport from EnderIOAddons]

CrashReport

Time: 26/05/2025 18:39
Description: Exception in server tick loop

java.lang.NullPointerException: Cannot invoke "net.minecraft.item.ItemStack.func_77973_b()" because "info.loenwind.enderioaddons.recipe.Recipes.capBankCreative" is null
	at Launch//info.loenwind.enderioaddons.plant.EioaGrowthRequirement.<init>(EioaGrowthRequirement.java:34)
	at Launch//info.loenwind.enderioaddons.plant.EioaCropPlant.<init>(EioaCropPlant.java:40)
	at Launch//info.loenwind.enderioaddons.machine.afarm.TileAfarm.registerPlants(TileAfarm.java:138)
	at Launch//info.loenwind.enderioaddons.machine.afarm.AgriDetector.registerPlants(AgriDetector.java:35)
	at Launch//info.loenwind.enderioaddons.proxy.ClientAndServerProxy.init(ClientAndServerProxy.java:66)
	at Launch//info.loenwind.enderioaddons.EnderIOAddons.init(EnderIOAddons.java:80)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at Launch//cpw.mods.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:532)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at Launch//com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
	at Launch//com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
	at Launch//com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
	at Launch//com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
	at Launch//com.google.common.eventbus.EventBus.post(EventBus.java:275)
	at Launch//cpw.mods.fml.common.LoadController.sendEventToModContainer(LoadController.java:212)
	at Launch//cpw.mods.fml.common.LoadController.propogateStateMessage(LoadController.java:190)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at Launch//com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
	at Launch//com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
	at Launch//com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
	at Launch//com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
	at Launch//com.google.common.eventbus.EventBus.post(EventBus.java:275)
	at Launch//cpw.mods.fml.common.LoadController.distributeStateMessage(LoadController.java:119)
	at Launch//cpw.mods.fml.common.Loader.initializeMods(Loader.java:739)
	at Launch//cpw.mods.fml.server.FMLServerHandler.finishServerLoading(FMLServerHandler.java:97)
	at Launch//cpw.mods.fml.common.FMLCommonHandler.onServerStarted(FMLCommonHandler.java:323)
	at Launch//net.minecraft.server.dedicated.DedicatedServer.func_71197_b(DedicatedServer.java:270)
	at Launch//net.minecraft.server.MinecraftServer.run(MinecraftServer.java:644)
	at java.base/java.lang.Thread.run(Thread.java:1583)

But this indeed make CustomNPCs work. (with script true on java 21)

Gonna ask for some friend to test on Dragonblock as is a mod with tons of crazy things to see if it works correctly.

EverNife avatar May 26 '25 22:05 EverNife

Tested with latest changes, my modpack still crashes (still enderioaddons only) [CrashReport from EnderIOAddons]

But this indeed make CustomNPCs work. (with script true on java 21)

Gonna ask for some friend to test on Dragonblock as is a mod with tons of crazy things to see if it works correctly.

This is trivially fixed by a solution that has already been found and is used, but which I did not write about here:

java @java9args.txt -cp libraries/com/gtnewhorizons/retrofuturabootstrap/RetroFuturaBootstrap/1.0.10/RetroFuturaBootstrap-1.0.10.jar:Crucible-1.7.10-all-patches-ec0120af-server.jar cpw.mods.fml.relauncher.ServerLaunchWrapper

gravit0 avatar Jun 03 '25 04:06 gravit0

Now these and other mods will work correctly without the need to fix the start.sh line

gravit0 avatar Jun 03 '25 05:06 gravit0

It seems its porperly working now :D

EverNife avatar Jun 03 '25 13:06 EverNife

ScriptEngineManager providers.next(): javax.script.ScriptEngineFactory: Provider org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory not found

Tengo este error con el power nbt, alguien sabe por que?

I'm getting this error with power nbt, does anyone know why?

elcorremachitos avatar Oct 14 '25 06:10 elcorremachitos