jira.codehaus.org

  • Log In Access more options
    • Online Help
    • Keyboard Shortcuts
    • About JIRA
    • JIRA Credits
    • What?s New
  • Dashboards Access more options (Alt+d)
  • Projects Access more options (Alt+p)
  • Issues Access more options (Alt+i)
Signup
EasyMock
  • EasyMock
  • EASYMOCK-108

Android support

  • Log In
  • Views
    • XML
    • Word
    • Printable

Details

  • Type: Improvement Improvement
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 3.1
  • Fix Version/s: 3.2
  • Component/s: Core
  • Labels:
    None
  • Environment:
    Android OS (all versions)
  • Testcase included:
    yes
  • Patch Submitted:
    Yes
  • Number of attachments :
    3

Description

Hi, I'm a member of Android's Dalvik team. Lots of Android developers have been asking for EasyMock support for Android, so we've written some code to make that possible.

The first part is a new library called 'dexmaker' that assumes the role of ASM+cglib on Android. Read more about dexmaker here:
http://code.google.com/p/dexmaker/
This library is not yet available in maven. Please let me know if this blocks forward progress on the patch; I'll see what I can do.

The second part is a patch to EasyMock to integrate dexmaker. The patch applies to SVN r269. I've attempted to avoid making unnecessary changes in the patch, though I admit it does require a lot of churn. The main change is that there's a new class, "AndroidClassProxyFactory" that compliments the existing "ClassProxyFactory". Much of the changes are in test code, cleaning up tests that fail on Android for various reasons. For example one test assumed implementation details about ArrayList that aren't true on Android.

Unfortunately it's slightly cumbersome to confirm that the tests pass on Android because there's no easy way to run JUnit 4 tests on Android. I hacked together the vogar test runner (http://code.google.com/p/vogar/) to run the tests; it would also be possible to run tests as a part of an Android application. All of the tests pass with the following exceptions:

  • org.easymock.tests.CglibTest#test (cglib doesn't run at all on Android)
  • org.easymock.tests2.SerializationTest#test (I elected to omit support for serialization; it's not popular on Android)
  • Options
    • Sort By Name
    • Sort By Date
    • Ascending
    • Descending
    • Download All

Attachments

  1. Hide
    Java Archive File
    dexmaker.jar
    11/Jan/12 11:29 PM
    657 kB
    Jesse Wilson
    1. File
      META-INF/MANIFEST.MF 0.1 kB
    2. File
      com/google/dexmaker/dx/Version.class 0.4 kB
    3. File
      com/google/dexmaker/.../cf/code/Merger.class 1 kB
    4. File
      com/google/dexmaker/.../dex/DexFormat.class 1 kB
    5. File
      com/google/dexmaker/.../dex/DexOptions.class 0.6 kB
    6. File
      com/google/dexmaker/dx/dex/SizeOf.class 0.7 kB
    7. File
      com/google/dexmaker/.../code/ArrayData.class 5 kB
    8. File
      com/google/.../code/BlockAddresses.class 3 kB
    9. File
      com/google/.../code/CatchBuilder.class 0.4 kB
    10. File
      com/google/.../CatchHandlerList$Entry.class 2 kB
    11. File
      com/google/.../code/CatchHandlerList.class 3 kB
    12. File
      com/google/.../code/CatchTable$Entry.class 2 kB
    13. File
      com/google/.../code/CatchTable.class 2 kB
    14. File
      com/google/.../code/CodeAddress.class 1 kB
    15. File
      com/google/dexmaker/.../code/CstInsn.class 3 kB
    16. File
      com/.../DalvCode$AssignIndicesCallback.class 0.3 kB
    17. File
      com/google/dexmaker/.../code/DalvCode.class 3 kB
    18. File
      com/google/dexmaker/.../code/DalvInsn.class 7 kB
    19. File
      com/google/.../code/DalvInsnList.class 5 kB
    20. File
      com/google/dexmaker/.../dex/code/Dop.class 2 kB
    21. File
      com/google/dexmaker/.../dex/code/Dops.class 20 kB
    22. File
      com/google/.../code/FixedSizeInsn.class 2 kB
    23. File
      com/google/.../code/HighRegisterPrefix.class 4 kB
    24. File
      com/google/.../code/InsnFormat.class 10 kB
    25. File
      com/google/dexmaker/.../code/LocalEnd.class 2 kB
    26. File
      com/google/.../LocalList$Disposition.class 1 kB
    27. File
      com/google/.../code/LocalList$Entry.class 4 kB
    28. File
      com/google/.../LocalList$MakeState.class 7 kB
    29. File
      com/google/dexmaker/.../code/LocalList.class 5 kB
    30. File
      com/google/.../code/LocalSnapshot.class 2 kB
    Showing 30 of 419 items Download Zip
    Show
    Java Archive File
    dexmaker.jar
    11/Jan/12 11:29 PM
    657 kB
    Jesse Wilson
  2. Text File
    easymock-on-android.patch
    11/Jan/12 11:29 PM
    41 kB
    Jesse Wilson
  3. Text File
    easymock-on-android20120305.patch
    05/Mar/12 9:48 PM
    44 kB
    Jesse Wilson

Activity

Ascending order - Click to sort in descending order
  • All
  • Comments
  • Work Log
  • History
  • Activity
Hide
Permalink
Jesse Wilson added a comment - 16/Jan/12 3:31 PM

In parallel with this contribution I've been preparing a similar contribution for Mockito. Over there we've created a new interface "MockMaker" that is implemented internally using cglib. When run on Android another implementation is selected automatically using ServiceLoader. This approach seems to work quite well and prevents Mockito from having a direct dependency on any Android-specific code.

Here's their tracking bug if you'd like to compare:
http://code.google.com/p/mockito/issues/detail?id=308

Show
Jesse Wilson added a comment - 16/Jan/12 3:31 PM In parallel with this contribution I've been preparing a similar contribution for Mockito. Over there we've created a new interface "MockMaker" that is implemented internally using cglib. When run on Android another implementation is selected automatically using ServiceLoader. This approach seems to work quite well and prevents Mockito from having a direct dependency on any Android-specific code. Here's their tracking bug if you'd like to compare: http://code.google.com/p/mockito/issues/detail?id=308
Hide
Permalink
Tom Leach added a comment - 02/Mar/12 11:18 AM - edited

@Jesse I'm attempting to get your patched version to build in order to test it as a replacement for android-mock, but so far with no luck.

I applied your patch to r269 of the EasyMock trunk and attempted to run mvn install but the build fails. It then occurred to me that it would probably need dexmaker.jar included as a dependency, so I added this to the pom.xml file as a system-scoped local dependency:

<dependency>
  <groupId>dexmaker</groupId>
  <artifactId>dexmaker-nodep</artifactId>
  <version>1.0</version>
  <scope>system</scope>
  <systemPath>${basedir}/lib/dexmaker.jar</systemPath>
</dependency>

The build got a little further, but I still get compile errors:

[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building EasyMock
[INFO]    task-segment: [install]
[INFO] ------------------------------------------------------------------------
[INFO] [timestamp:create {execution: date}]
[INFO] [timestamp:create {execution: year}]
[INFO] [remote-resources:process {execution: default}]
[debug] execute contextualize
[INFO] [resources:resources {execution: default-resources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/resources
[INFO] Copying 2 resources
[INFO] [compiler:compile {execution: default-compile}]
[WARNING] File encoding has not been set, using platform encoding MacRoman, i.e. build is platform dependent!
[INFO] Compiling 71 source files to /Users/tom/Code/third_party/easymock/trunk/easymock/target/classes
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/ClassProxyFactory.java:[40,58] type org.easymock.internal.IProxyFactory does not take parameters
[ERROR] /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/AndroidClassProxyFactory.java:[46,61] getConstructorToUse(java.lang.Class<?>) has private access in org.easymock.internal.DefaultClassInstantiator
[ERROR] /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/AndroidClassProxyFactory.java:[47,50] getArgsForTypes(java.lang.Class<?>[]) has private access in org.easymock.internal.DefaultClassInstantiator
[ERROR] /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/AndroidClassProxyFactory.java:[84,40] cannot find symbol
symbol  : method isCallerMockInvocationHandlerInvoke(java.lang.Throwable)
location: class org.easymock.internal.ClassProxyFactory
[ERROR] /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/MocksControl.java:[122,39] incompatible types
found   : org.easymock.internal.ClassProxyFactory
required: org.easymock.internal.IProxyFactory
[ERROR] /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/ClassProxyFactory.java:[182,16] cannot find symbol
symbol  : variable ClassExtensionHelper
location: class org.easymock.internal.ClassProxyFactory<T>
[ERROR] /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/ClassProxyFactory.java:[184,45] cannot find symbol
symbol  : variable ClassExtensionHelper
location: class org.easymock.internal.ClassProxyFactory<T>
[INFO] 7 errors 
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Compilation failure

/Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/ClassProxyFactory.java:[40,58] type org.easymock.internal.IProxyFactory does not take parameters
/Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/AndroidClassProxyFactory.java:[46,61] getConstructorToUse(java.lang.Class<?>) has private access in org.easymock.internal.DefaultClassInstantiator
/Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/AndroidClassProxyFactory.java:[47,50] getArgsForTypes(java.lang.Class<?>[]) has private access in org.easymock.internal.DefaultClassInstantiator
/Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/AndroidClassProxyFactory.java:[84,40] cannot find symbol
symbol  : method isCallerMockInvocationHandlerInvoke(java.lang.Throwable)
location: class org.easymock.internal.ClassProxyFactory
/Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/MocksControl.java:[122,39] incompatible types
found   : org.easymock.internal.ClassProxyFactory
required: org.easymock.internal.IProxyFactory
/Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/ClassProxyFactory.java:[182,16] cannot find symbol
symbol  : variable ClassExtensionHelper
location: class org.easymock.internal.ClassProxyFactory<T>
/Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/ClassProxyFactory.java:[184,45] cannot find symbol
symbol  : variable ClassExtensionHelper
location: class org.easymock.internal.ClassProxyFactory<T>

[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 seconds
[INFO] Finished at: Fri Mar 02 11:03:30 CST 2012
[INFO] Final Memory: 26M/81M
[INFO] ------------------------------------------------------------------------

Any hints where I might be going wrong? Alternatively, any chance you could attach a JAR you've already built ?

Show
Tom Leach added a comment - 02/Mar/12 11:18 AM - edited @Jesse I'm attempting to get your patched version to build in order to test it as a replacement for android-mock , but so far with no luck. I applied your patch to r269 of the EasyMock trunk and attempted to run mvn install but the build fails. It then occurred to me that it would probably need dexmaker.jar included as a dependency, so I added this to the pom.xml file as a system-scoped local dependency: <dependency> <groupId> dexmaker </groupId> <artifactId> dexmaker-nodep </artifactId> <version> 1.0 </version> <scope> system </scope> <systemPath> ${basedir}/lib/dexmaker.jar </systemPath> </dependency> The build got a little further, but I still get compile errors: [INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Building EasyMock [INFO] task-segment: [install] [INFO] ------------------------------------------------------------------------ [INFO] [timestamp:create {execution: date}] [INFO] [timestamp:create {execution: year}] [INFO] [remote-resources:process {execution: default}] [debug] execute contextualize [INFO] [resources:resources {execution: default-resources}] [WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/resources [INFO] Copying 2 resources [INFO] [compiler:compile {execution: default-compile}] [WARNING] File encoding has not been set, using platform encoding MacRoman, i.e. build is platform dependent! [INFO] Compiling 71 source files to /Users/tom/Code/third_party/easymock/trunk/easymock/target/classes [INFO] ------------------------------------------------------------- [ERROR] COMPILATION ERROR : [INFO] ------------------------------------------------------------- [ERROR] /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/ClassProxyFactory.java:[40,58] type org.easymock.internal.IProxyFactory does not take parameters [ERROR] /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/AndroidClassProxyFactory.java:[46,61] getConstructorToUse(java.lang.Class<?>) has private access in org.easymock.internal.DefaultClassInstantiator [ERROR] /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/AndroidClassProxyFactory.java:[47,50] getArgsForTypes(java.lang.Class<?>[]) has private access in org.easymock.internal.DefaultClassInstantiator [ERROR] /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/AndroidClassProxyFactory.java:[84,40] cannot find symbol symbol : method isCallerMockInvocationHandlerInvoke(java.lang.Throwable) location: class org.easymock.internal.ClassProxyFactory [ERROR] /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/MocksControl.java:[122,39] incompatible types found : org.easymock.internal.ClassProxyFactory required: org.easymock.internal.IProxyFactory [ERROR] /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/ClassProxyFactory.java:[182,16] cannot find symbol symbol : variable ClassExtensionHelper location: class org.easymock.internal.ClassProxyFactory<T> [ERROR] /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/ClassProxyFactory.java:[184,45] cannot find symbol symbol : variable ClassExtensionHelper location: class org.easymock.internal.ClassProxyFactory<T> [INFO] 7 errors [INFO] ------------------------------------------------------------- [INFO] ------------------------------------------------------------------------ [ERROR] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Compilation failure /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/ClassProxyFactory.java:[40,58] type org.easymock.internal.IProxyFactory does not take parameters /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/AndroidClassProxyFactory.java:[46,61] getConstructorToUse(java.lang.Class<?>) has private access in org.easymock.internal.DefaultClassInstantiator /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/AndroidClassProxyFactory.java:[47,50] getArgsForTypes(java.lang.Class<?>[]) has private access in org.easymock.internal.DefaultClassInstantiator /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/AndroidClassProxyFactory.java:[84,40] cannot find symbol symbol : method isCallerMockInvocationHandlerInvoke(java.lang.Throwable) location: class org.easymock.internal.ClassProxyFactory /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/MocksControl.java:[122,39] incompatible types found : org.easymock.internal.ClassProxyFactory required: org.easymock.internal.IProxyFactory /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/ClassProxyFactory.java:[182,16] cannot find symbol symbol : variable ClassExtensionHelper location: class org.easymock.internal.ClassProxyFactory<T> /Users/tom/Code/third_party/easymock/trunk/easymock/src/main/java/org/easymock/internal/ClassProxyFactory.java:[184,45] cannot find symbol symbol : variable ClassExtensionHelper location: class org.easymock.internal.ClassProxyFactory<T> [INFO] ------------------------------------------------------------------------ [INFO] For more information, run Maven with the -e switch [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3 seconds [INFO] Finished at: Fri Mar 02 11:03:30 CST 2012 [INFO] Final Memory: 26M/81M [INFO] ------------------------------------------------------------------------ Any hints where I might be going wrong? Alternatively, any chance you could attach a JAR you've already built ?
Hide
Permalink
Jesse Wilson added a comment - 03/Mar/12 12:25 PM

Tom, the dexmerge code has undergone some changes since I first sent this out; I'll take a look.

There are probably also some small structural changes I can make that'll simplify deployment of easymock+Android... On the related Mockito change we made the mock class generator pluggable. When running on a JVM everything is the same; when running on an Android with dexmaker.jar on your classpath it picks that up instead. We should use the same strategy with EasyMock: provide a service interface and a simple mechanism to look up its implementation.

Show
Jesse Wilson added a comment - 03/Mar/12 12:25 PM Tom, the dexmerge code has undergone some changes since I first sent this out; I'll take a look. There are probably also some small structural changes I can make that'll simplify deployment of easymock+Android... On the related Mockito change we made the mock class generator pluggable. When running on a JVM everything is the same; when running on an Android with dexmaker.jar on your classpath it picks that up instead. We should use the same strategy with EasyMock: provide a service interface and a simple mechanism to look up its implementation.
Hide
Permalink
Jesse Wilson added a comment - 05/Mar/12 9:48 PM

This should patch cleanly on SVN r272.

Show
Jesse Wilson added a comment - 05/Mar/12 9:48 PM This should patch cleanly on SVN r272.
Hide
Permalink
Henri Tremblay added a comment - 12/Feb/13 5:32 PM

The patch was applied almost as is except for some tests that were failing.

Show
Henri Tremblay added a comment - 12/Feb/13 5:32 PM The patch was applied almost as is except for some tests that were failing.

People

  • Assignee:
    Henri Tremblay
    Reporter:
    Jesse Wilson
Vote (2)
Watch (3)

Dates

  • Created:
    11/Jan/12 11:29 PM
    Updated:
    12/Feb/13 5:32 PM
    Resolved:
    12/Feb/13 5:32 PM

Time Tracking

Estimated:
2w
Original Estimate - 2 weeks
Remaining:
2w
Remaining Estimate - 2 weeks
Logged:
Not Specified
Time Spent - Not Specified
  • Atlassian JIRA (v5.2.7#850-sha1:b2af0c8)
  • Report a problem
  • Powered by a free Atlassian JIRA open source license for Codehaus. Try JIRA - bug tracking software for your team.