Closed ScottCowe closed 3 years ago
Hi @MisterCow1 !
As a test, if you also use -dontobfuscate
does the problem disappear? You mention you have already disabled optimization and shrinking, so this would also rule out or confirm obfuscation as well.
Have you tried adding a keep rule for dev/mistercow1/sobyity/EventBus.call(Ldev/mistercow1/sobyity/Event;)V
?
Could you show the bytecode of dev/mistercow1/sobyity/EventBus.call(Ldev/mistercow1/sobyity/Event;)V
- you can print it with javap -c -v -p -cp my.jar dev.mistercow1.sobyity.EventBus
I have added -dontobfuscate
and it seems like Minecraft still crashes with the java.lang.VerifyError: Bad type on operand stack
error. However, in the mod jar that has not been modified by proguard it works fine.
dev/mistercow1/sobyity/EventBus.call(Ldev/mistercow1/sobyity/Event;)V
is being kept, along with the entire sobyity library. My Minecraft mod is separate from this, but sobyity is included in the jar, unobfuscted.
Bytecode for dev/mistercow1/sobyity/EventBus.call(Ldev/mistercow1/sobyity/Event;)V
is as follows:
public void call(dev.mistercow1.sobyity.Event);
descriptor: (Ldev/mistercow1/sobyity/Event;)V
flags: (0x0001) ACC_PUBLIC
Code:
stack=6, locals=4, args_size=2
0: aload_1
1: invokevirtual #22 // Method java/lang/Object.getClass:()Ljava/lang/Class;
4: invokestatic #17 // Method get:(Ljava/lang/Class;)Ldev/mistercow1/sobyity/EventData;
7: astore_2
8: aload_2
9: getfield #16 // Field dev/mistercow1/sobyity/EventData.target:Ljava/lang/reflect/Method;
12: aload_2
13: getfield #15 // Field dev/mistercow1/sobyity/EventData.source:Ljava/lang/Class;
16: iconst_1
17: anewarray #8 // class java/lang/Object
20: dup
21: iconst_0
22: aload_1
23: aastore
24: invokevirtual #26 // Method java/lang/reflect/Method.invoke:(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
27: pop
28: goto 36
31: astore_3
32: aload_3
33: invokevirtual #23 // Method java/lang/ReflectiveOperationException.printStackTrace:()V
36: return
Exception table:
from to target type
8 28 31 Class java/lang/reflect/InvocationTargetException
8 28 31 Class java/lang/IllegalAccessException
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 31
locals = []
stack = [ class java/lang/Object ]
frame_type = 4 /* same */
It looks like the type in the StackMapTable
is wrong - at offset 31 there should be an exception on the stack since that's the start of the exception handler. This could be a problem with the preverifier since that's where these stack map tables are generated in ProGuard.
-dontpreverify
and show the bytecode?Original bytecode for call method is as follows:
public void call(dev.mistercow1.sobyity.Event);
descriptor: (Ldev/mistercow1/sobyity/Event;)V
flags: (0x0001) ACC_PUBLIC
Code:
stack=6, locals=4, args_size=2
0: aload_1
1: invokevirtual #98 // Method java/lang/Object.getClass:()Ljava/lang/Class;
4: invokestatic #100 // Method get:(Ljava/lang/Class;)Ldev/mistercow1/sobyity/EventData;
7: astore_2
8: aload_2
9: getfield #72 // Field dev/mistercow1/sobyity/EventData.target:Ljava/lang/reflect/Method;
12: aload_2
13: getfield #103 // Field dev/mistercow1/sobyity/EventData.source:Ljava/lang/Class;
16: iconst_1
17: anewarray #4 // class java/lang/Object
20: dup
21: iconst_0
22: aload_1
23: aastore
24: invokevirtual #107 // Method java/lang/reflect/Method.invoke:(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
27: pop
28: goto 36
31: astore_3
32: aload_3
33: invokevirtual #114 // Method java/lang/ReflectiveOperationException.printStackTrace:()V
36: return
Exception table:
from to target type
8 28 31 Class java/lang/reflect/InvocationTargetException
8 28 31 Class java/lang/IllegalAccessException
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 31
locals = [ class dev/mistercow1/sobyity/EventBus, class dev/mistercow1/sobyity/Event, class dev/mistercow1/sobyity/EventData ]
stack = [ class java/lang/ReflectiveOperationException ]
frame_type = 4 /* same */
LineNumberTable:
line 166: 0
line 171: 8
line 176: 28
line 173: 31
line 175: 32
line 177: 36
LocalVariableTable:
Start Length Slot Name Signature
32 4 3 e Ljava/lang/ReflectiveOperationException;
0 37 0 this Ldev/mistercow1/sobyity/EventBus;
0 37 1 event Ldev/mistercow1/sobyity/Event;
8 29 2 data Ldev/mistercow1/sobyity/EventData;
Bytecode with -dontpreverify
is as follows:
public void call(dev.mistercow1.sobyity.Event);
descriptor: (Ldev/mistercow1/sobyity/Event;)V
flags: (0x0001) ACC_PUBLIC
Code:
stack=6, locals=4, args_size=2
0: aload_1
1: invokevirtual #20 // Method java/lang/Object.getClass:()Ljava/lang/Class;
4: invokestatic #15 // Method get:(Ljava/lang/Class;)Ldev/mistercow1/sobyity/EventData;
7: astore_2
8: aload_2
9: getfield #14 // Field dev/mistercow1/sobyity/EventData.target:Ljava/lang/reflect/Method;
12: aload_2
13: getfield #13 // Field dev/mistercow1/sobyity/EventData.source:Ljava/lang/Class;
16: iconst_1
17: anewarray #6 // class java/lang/Object
20: dup
21: iconst_0
22: aload_1
23: aastore
24: invokevirtual #24 // Method java/lang/reflect/Method.invoke:(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
27: pop
28: goto 36
31: astore_3
32: aload_3
33: invokevirtual #21 // Method java/lang/ReflectiveOperationException.printStackTrace:()V
36: return
Exception table:
from to target type
8 28 31 Class java/lang/reflect/InvocationTargetException
8 28 31 Class java/lang/IllegalAccessException
The problem is that ProGuard outputs e
as Object
instead of ReflectiveOperationException
in the preverification attribute, which then upsets the java verifier.
Did ProGuard complain about not finding common superclasses, and did you then add ProGuard options -ignorewarnings
or -dontwarn
to get around these warnings? This could lead to problems if some classes are missing from the input. For example, Java 6 didn't have ReflectiveOperationException
yet. Are you specifying the proper version of the Java runtime with -libraryjars
?
Adding the jmods to -libraryjars
fixed the issue, thanks!
I have a Fabric 1.17.1 (Java 16) mod for Minecraft that I am trying to obfuscate. Included with this mod is my event system that handles all the events for my mod. This event system uses the invoke method to call events in my event listener class at runtime.
Here is the the event I am calling using the call method:
Here is the call method:
I am also using mixins to register my event listener class, which works fine.
In a development enviroment this works fine and my minecraft mod runs. However, when I build my mod and attempt to use it in the Minecraft launcher it crashed, with the crash report of:
dev/mistercow1/sobyity/EventBus.call(Ldev/mistercow1/sobyity/Event;)V @33
is the invoke in my call method.In my proguard mappings I have excluded the event library and the mixin package (so they do not get obfuscated), as that is required for minecraft to run, as it is packaged into the jar using shadowjar. I have also disabled shrinking and optimizing, and repackaged classes into the base directory (dev.mistercow1.minecraftmod)
Everything works fine in the deobfuscated version of my mod and in the development enviroment, so I am confused why the obfuscated version does not work.
I have already tried using
data.target.invoke(null, event);
instead, but it has no effect.Is this a problem with proguard or my event system or minecraft mod?
Does anyone have any solutions?