3

I'm currently trying to redefine the CraftPlayer class in spigot to add more events. I'm using Byte-Buddy and ASM to edit the classes using this utility class. However, even when running CraftPlayer::class.java.redefine { } (which doesn't change the class at all) I get a java.lang.VerifyError without any message.

I've tried running the same code on other large, complicated classes and didn't get an error. The only difference between these classes and CraftPlayer is that they don't have any inner classes.

Full Exception:

java.lang.VerifyError: null
        at sun.instrument.InstrumentationImpl.redefineClasses0(Native Method) ~[?:?]
        at sun.instrument.InstrumentationImpl.redefineClasses(InstrumentationImpl.java:194) ~[?:?]
        at xyz.xenondevs.lib.bytebase.RuntimeUtilsKt.insertInstructions$redefineClasses(RuntimeUtils.kt:41) ~[?:?]
        at xyz.xenondevs.lib.bytebase.RuntimeUtilsKt.access$insertInstructions$redefineClasses(RuntimeUtils.kt:1) ~[?:?]
        at xyz.xenondevs.lib.bytebase.RuntimeUtilsKt$insertInstructions$2.invoke(RuntimeUtils.kt:41) ~[?:?]
        at xyz.xenondevs.lib.bytebase.RuntimeUtilsKt$insertInstructions$2.invoke(RuntimeUtils.kt:41) ~[?:?]
        at xyz.xenondevs.lib.bytebase.RuntimeUtilsKt$sam$java_util_function_Consumer$0.accept(RuntimeUtils.kt) ~[?:?]
        at java.util.ArrayList.forEach(ArrayList.java:1511) ~[?:?]
        at xyz.xenondevs.lib.bytebase.RuntimeUtilsKt.insertInstructions(RuntimeUtils.kt:41) ~[?:?]
        at xyz.xenondevs.test.TestPlugin.onEnable(TestPlugin.kt:11) ~[?:?]
        at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:264) ~[spigot-1.17.1.jar:3241-Spigot-6c1c1b2-1492826]
        at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:342) ~[spigot-1.17.1.jar:3241-Spigot-6c1c1b2-1492826]
        at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:480) ~[spigot-1.17.1.jar:3241-Spigot-6c1c1b2-1492826]
        at org.bukkit.craftbukkit.v1_17_R1.CraftServer.enablePlugin(CraftServer.java:511) ~[spigot-1.17.1.jar:3241-Spigot-6c1c1b2-1492826]
        at org.bukkit.craftbukkit.v1_17_R1.CraftServer.enablePlugins(CraftServer.java:425) ~[spigot-1.17.1.jar:3241-Spigot-6c1c1b2-1492826]
        at net.minecraft.server.MinecraftServer.loadWorld(MinecraftServer.java:619) ~[spigot-1.17.1.jar:3241-Spigot-6c1c1b2-1492826]
        at net.minecraft.server.dedicated.DedicatedServer.init(DedicatedServer.java:266) ~[spigot-1.17.1.jar:3241-Spigot-6c1c1b2-1492826]
        at net.minecraft.server.MinecraftServer.x(MinecraftServer.java:1010) ~[spigot-1.17.1.jar:3241-Spigot-6c1c1b2-1492826]
        at net.minecraft.server.MinecraftServer.lambda$0(MinecraftServer.java:305) ~[spigot-1.17.1.jar:3241-Spigot-6c1c1b2-1492826]
        at java.lang.Thread.run(Thread.java:831) [?:?]

I'm running Java 16 build 16.0.1+9-24

Why does the JVM fail to verify the CraftPlayer class even though nothing has changed?

ByteZ
  • 131
  • 1
  • 6
  • 2
    This is unlikely caused by Byte Buddy. Your transformer generates bytecode that is not valid, it seems. You need to look in this direction. – Rafael Winterhalter Nov 14 '21 at 20:04
  • 1
    As I mentioned above, This error also occurs when I try redefining the class without any changes. I've even exported the class file generated by asm, and it was the exact same class. Also, shouldn't the VerifyError contain more information if the bytecode was invalid? – ByteZ Nov 14 '21 at 20:18
  • 1
    You can set `-Dnet.bytebuddy.dump=/some/folder` to get the input and output byte code written to some folder. On redefinition, the verification error is unfortunately often not explained by the VM. – Rafael Winterhalter Nov 14 '21 at 21:33
  • 1
    I already dumped both classes and compared them. They looked the exact same. I'm only using ByteBuddy to get an instrumentation instance, so I doubt ``-Dnet.bytebuddy.dump=/some/folder`` would even work. – ByteZ Nov 14 '21 at 22:16
  • 2
    I had this once in the past that a class file was treated differently depending on whether it was loaded from disk or passed to `defineClass` manually. But that’s a rare corner case. Perhaps, it helps when you provide the actual class file… – Holger Nov 15 '21 at 11:06
  • 1
    @Holger [Here](https://download.getbukkit.org/spigot/spigot-1.17.1.jar) is a download link to the jar. The full path to the class is ``org/bukkit/craftbukkit/v1_17_R1/entity/CraftPlayer`` – ByteZ Nov 15 '21 at 12:56

1 Answers1

1

Seems to have been a JVM/asm bug. Just tried it again with Java 17 and updated dependencies but the exact same code, and it appears to be working now.

ByteZ
  • 131
  • 1
  • 6