Menu

#538 Inlining bug when turning package protected method in public from another package that has class hierarchy

v4.10
open-accepted
5
2014-09-26
2014-08-28
No

When inlining a function call, Proguard adds the keyword "public" to access a method that was previously 'package protected'. However, only the parent's class method is turned public, the child classe's overriding methods are kept 'package protected'.

The result is the correct function is no longer being called in the child when I call 'a.doSomething()' from example below...

Let say I have :

Package 1

public class a {
    private b proxy;

    private void doSomething() {
        proxy.proxyMethod();
    }
}

Package 2

class b {
    private State currentState;

    public void proxyMethod {
        currentState.method();
    }
}

public abstract class State {
    void method() {

    }
}

public class State extends SubState {
    void method() {
        // I override method from parent
    }
}

In class 'a', Proguard chose to directly call the method by doing the following:

  1. make 'b.currentState' public.
  2. make 'State.method()' public.
  3. replace call 'proxy.proxyMethod()' in class 'a' by 'proxy.currentState.method()'.
  4. Strip 'proxyMethod' from class 'b' since it's no longer needed.

However, while doing step #2, it forgets to make the method 'method()' public for child classes as well! The child's overridden method is not getting called anymore but instead the parent's class method because it's access stayed 'package protected'.

I have confirmed that this bug is present in 4.10, 4.11 and 5.0.

Our workaround currently is to add a NOP call (a call to our logger) so proguard doesn't decide to inline the function call. But who knows if this problem is also happening in other parts of our code?

Discussion

  • Eric Lafortune

    Eric Lafortune - 2014-09-09

    Thanks for your thorough analysis. I can reproduce the behavior, obtaining a public method with a package visible method that overrides it. That's not very pretty, but the Java VM and the Dalvik VM both appear to handle it, calling the package visible method, as intended. Are you perhaps using a different VM?

    In any case, I'll see what I can do to change/fix the behavior.

     
  • Eric Lafortune

    Eric Lafortune - 2014-09-09
    • status: open --> open-accepted
    • assigned_to: Eric Lafortune
    • Priority: 2 --> 5
     
  • Jérémie Faucher-Goulet

    You are correct... We are using a VM provided by Gemalto/Cinterion for their M2M products. This is a J2ME project using the following profiles: CLDC 1.1 and IMP-NG (JSR 228)!

    We are currently avoiding the problem by making the methods public beforehand in that specific case. Our worry is that we may have the same problem elsewhere in our code where it doesn't trigger an obvious error.

     

    Last edit: Jérémie Faucher-Goulet 2014-09-26

Log in to post a comment.

MongoDB Logo MongoDB