Skip to content

Weird reobfuscation error with scala traits causes AbstractMethodError when running in obfuscated environment #31

@bdew

Description

@bdew

This happens if a scala trait that doesn't extend a vanilla class declares a method with the same name as something in a vanilla class, then a class mixes this trait with that class, for example:

trait A {
  def getWorldObj: World
}

class B extends TileEntity with A

object C {
  def foo(p: A) = p.getWorldObj
  def bar(p: B) = p.getWorldObj
}

This compiles and works correctly in an unobfuscated environment.
After reobfuscation C.bar gets changed to the obfuscated name as expected

0: aload_1       
1: invokevirtual #30                 // Method test/B.func_145831_w:()Lnet/minecraft/world/World;
4: areturn       

But the interface and C.foo still refers to the unobfuscated name

0: aload_1       
1: invokeinterface #20,  1           // InterfaceMethod test/A.getWorldObj:()Lnet/minecraft/world/World;
6: areturn       

And a call to C.foo will crash with

java.lang.AbstractMethodError: test.B.getWorldObj()Lnet/minecraft/world/World;

I made a minimal project to demonstrate the issue - it will crash in PreInit when running in an obfuscated environment.

Same thing can also happen in java (though i guess it's less common to do something like that without mixins)

public interface A {
    World getWorldObj();
}

public class B extends TileEntity implements A {
}

public class C {
    static World foo(A p) {
        return p.getWorldObj();
    }

    static World foo(B p) {
        return p.getWorldObj();
    }
}

Gives exactly the same result.

I'm not even sure how this can be fixed, creating a synthetic bridge method during reobfuscation? Would that be possible or even be a good idea?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions