Search code examples
androidspoon

No "unaligned" apks are generated with gradle plugin 2.2.0, breaking Spoon runner


Using android gradle plugin 2.2.0:

buildscript {
    repositories {
        maven { url "https://plugins.gradle.org/m2/" }
    }

    dependencies {
        classpath "com.android.tools.build:gradle:2.2.0"
    }
}

and running ./gradlew assembleDebug assembleDebugAndroidTest:

with 2.2.0:

app-debug.apk
app-debug-androidTest.apk

with 2.1.3:

app-debug.apk
app-debug-unaligned.apk
app-debug-androidTest.apk
app-debug-androidTest-unaligned.apk

Based on this google issue: https://code.google.com/p/android/issues/detail?id=212591 and comment here: https://code.google.com/p/android/issues/detail?id=212591#c15:

Hi, we don't generate unaligned apks any more. As part of the improvements to speed things, we generate the apk already aligned. So, instead of two, you just get the final one.

Spoon requires these "unaligned" apks to run it's test runner:

java -jar spoon-runner-1.7.0-jar-with-dependencies.jar \
    --debug --fail-on-failure --adb-timeout 90 --no-animations \
    --apk app-debug.apk \
    --test-apk app-debug-androidTest-unaligned.apk

Error:

12:06:48 I/InstrumentationResultParser: test run failed: 'Instrumentation run failed due to 'java.lang.NoClassDefFoundError''
2016-09-23 12:06:48 [STRL.testRunStarted] testCount=0 runName=<>.test
2016-09-23 12:06:48 [STRL.testRunFailed] errorMessage=Instrumentation run failed due to 'java.lang.NoClassDefFoundError'
2016-09-23 12:06:48 [STRL.testRunEnded] elapsedTime=0
12:06:48 I/XmlResultReporter: XML test result file generated at /<>/spoon-output/junit-reports/emulator-5554.xml. Total tests 0, 

It looks like Spoon only takes in the "unaligned".

Exception in thread "main" java.lang.IllegalArgumentException: Instrumentation APK path does not exist.
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122)
    at com.squareup.spoon.SpoonRunner$Builder.setInstrumentationApk(SpoonRunner.java:360)
    at com.squareup.spoon.SpoonRunner.main(SpoonRunner.java:657)

Solution

  • Before 2.2, the gradle plugin would generate an unaligned apk and then run zipalign to align it. So, two apks were produced one with "-unaligned" and one, aligned without any particular markings.

    With 2.2 there were many improvements in the build pipeline related to this:

    • APKs are now built incrementally, meaning when a single file is changed, only that file is updated in the APK.
    • APKs are generated aligned, no need for an extra alignment step.

    The last of these two enable V2 signatures in the APK (https://source.android.com/security/apksigning/v2.html): full-APK signatures that are resistant to any changes in the APK (and faster to verify). This means zipalign can no longer run on APKs that have these signatures enabled.

    So, to make the story short, starting with 2.2 packaging is faster, incremental and does not generate unnecessary unaligned APKs.