Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
bdew opened this issue Mar 18, 2015 · 4 comments

Comments

@bdew
Copy link

bdew commented Mar 18, 2015

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.

@bdew
Copy link
Author

bdew commented Mar 18, 2015

Thinking about this some more this is not specific to scala, you can get the same result with java

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?

@AbrarSyed
Copy link
Member

ForgeGradle does no do any obfuscation itself. I simply hand the jar over to SpecialSource for obfuscation. It would be within your best interest to open on an issue on that project.

@matthewprenger
Copy link

Looks like the same issue? md-5/SpecialSource#12

@bdew
Copy link
Author

bdew commented Mar 18, 2015

Sorry, wasn't aware that SS has it's own tracker.

I've opened md-5/SpecialSource#31 literaly seconds before @matthewprenger posted about md-5/SpecialSource#12. I'm not sure if it's the same issue.

CodesCubesAndCrashes added a commit to CodesCubesAndCrashes/AgriCraft that referenced this issue Jun 15, 2017
For the IAgriCrop interface, this renames the getPos and getWorld
methods so as to not match the methods inherited from TileEntity.
The only uses so far were in the mutation strategies. And the newly
named methods just call the original named methods via 'this'.

This workaround is for a re-obfuscation bug in Special Source, a
program that ForgeGradle depends on.

MinecraftForge/ForgeGradle#205
md-5/SpecialSource#12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants