qdrzwd / dexmaker

Automatically exported from code.google.com/p/dexmaker
0 stars 0 forks source link

ProxyBuilder.getMethodsToProxyRecursive adds final methods from base classes #12

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?

Create a class Foo like this:

public class Foo {
    public final String toString() {
        return "bar";
    }
}

Then (for example), try to do mock(Foo.class) with Mockito.

What is the expected output? What do you see instead?

I expect a mock object that does not mock toString().  Instead, a 
java.lang.VirtualMachineError is thrown because the proxy tried to override 
toString().

What version of the product are you using? On what operating system?

Latest git, compiled on Linux, running on Android 4.1.1.

Please provide any additional information below.

getMethodsToProxyRecursive() walks the class hierarchy, calling 
getMethodsToProxy() for each superclass.  So even though getMethodsToProxy() 
doesn't add the toString() method from Foo, it finds the non-final version in 
Object and adds it.

It seems to me that you could just use Class#getMethods(), rather than 
recursively calling Class#getDeclaredMethods() on the inheritance graph.

Original issue reported on code.google.com by tavian.b...@maluuba.com on 5 Aug 2012 at 8:16

GoogleCodeExporter commented 8 years ago
Unfortunately we can't use Class.getMethods() because that doesn't include 
package-private or protected methods.

Here's a test that demonstrates the bug:
https://code.google.com/p/dexmaker/source/detail?r=cbc8f32b9113fa3418fa5514c1dc7
f06dee26b1d

When run like this:
  vogar --device-dir /data/dexmaker --sourcepath dx/src/main/java/ --sourcepath dexmaker/src/main/java/ dexmaker/src/test/java/com/google/dexmaker/stock/ProxyBuilderTest.java

It fails like this:
  com.google.dexmaker.stock.ProxyBuilderTest#testFinalToString
    java.lang.VirtualMachineError
        at dalvik.system.DexFile.defineClass(Native Method)
        at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:211)
        at dalvik.system.DexPathList.findClass(DexPathList.java:315)
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:58)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
        at com.google.dexmaker.stock.ProxyBuilder.loadClass(ProxyBuilder.java:272)
        at com.google.dexmaker.stock.ProxyBuilder.buildProxyClass(ProxyBuilder.java:254)
        at com.google.dexmaker.stock.ProxyBuilder.build(ProxyBuilder.java:205)
        at com.google.dexmaker.stock.ProxyBuilderTest.testFinalToString(ProxyBuilderTest.java:781)

Original comment by limpbizkit on 10 Oct 2012 at 4:09

GoogleCodeExporter commented 8 years ago
This issue is fixed in 
https://code.google.com/p/dexmaker/source/detail?r=53327acdcf6b9f83b2974b96c6042
d5b004e45f9.

Original comment by klyu...@google.com on 12 Oct 2012 at 3:37