Today i’ve spent the entire day on tracking down a very very bad issue happening with the latest ‘com.android.tools.build:gradle:2.1.0’….

Incase you do not want to read the wall of text, there is a TL;DR at the bottom.

(Update, google has resolved this issue with their latest ‘com.android.tools.build:gradle:2.2.0-alpha2’)

https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened&groupby=&sort=&id=211738

Backstory

A customer reported that he could not install the latest update of their application on devices using an android version pre lollipop.

The error reported from google play when trying to install the update was the error -103.

Google play support is recommending users todo these following steps:

Solution 1 — Restart your Network Connection. Solution 2 — Restart your Android Phone. Solution 3 — Clear Cache and Data of Google Play Store, Google Service Framework and Download Manager. Solution 4 — Re-configure your Google Account.

It’s complete and utterly useless.

Investigation and some rambling

Google play support was not gonna be helpful. So I hoped that adb would shed some light on the issue, and sure it did. When running a adb install APP.apk it displayed:

Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]

My first reaction was a simple but firm: WHAT the ****!!!!!!. I tested the application myself before i uploaded it to google play!

However, i remember i only tested the CI deployment on modern devices, and not on devices running pre lollipop…..

And sure enough, this was a certificate issue bound only to android 4.3–5.0 for only updated code. Again WHAT?!?!!?

I tried to google the issue, and the top result was:

http://stackoverflow.com/questions/2914105/android-what-is-install-parse-failed-no-certificates-error

People suggested that it was a jarsigner problem between java versions, or that you needed to add:

-sigalg SHA1withRSA -digestalg SHA1 and manually sign and zipalign your unaligned apk. Sure I tried that, but it did not help. In fact, I got problems that made me even more confused.

So I started looking at the keystore-file and the published apk file.

They were identical when i ran:

keytool -list -v -keystore “file.keystore”

and

keytool -list -printcert -jarfile “app.apk”

and then I remembered the customer said “We did not get the update working for an android 4.3 device” which meant that they original application working once…

So I also ran keytool on the first uploaded apk-file to google play.

Same response as the keytool results above……

More headache

Nothing made sense. The fun thing about all this, is that the application is a branded app. Which means the same codebase is build for several customers, with new colors and resources.

And the code worked flawlessly for all but one of the cases.

I then noticed the keytool result saying: SHA1withDSA for the application that did not work. And the others that did work as expected was running:

SHA1withRSA…

Okey, so i thought that, DSA was maybe not implemented on android 4.3 to 5.0? The answer? It is.

How on earth could the certificate work and be installable on one build but on the next not?

I tried to compile the same project on another computer. Same problem.

I looked through my environment setup, nothing wrong with java or the certificate paths.

I started talking with another developer here at the office, and noticed we switched both buildTools and upgraded com.android.tools.build:gradle for the project, when the new Android Studio 2.1 stable version came…

The solution

So knowing what was changed, we tried to revert back to a gradle-wrapper.properties using:

distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip

and a project directory with build.gradle containing:

classpath ‘com.android.tools.build:gradle:1.3.0’

We build the previous update, but now running the old gradle build tools. And sure enough….. The application update now is installable

and is up on google play.

TL;DR

com.android.tools.build:gradle:2.1.0 does not like keystores using the signature algoritm SHA1withDSA at all. SHA1withRSA works just wonderful, but SHA1withDSA it for whatever reason does not report any failure, but never the less will upload to google play without any issues…

but not work.

The easiest solution, without replacing your keystore with new one containing SHA1withRSA is to instead use classpath ‘com.android.tools.build:gradle:1.3.0’

And rebuild your signed apk..

Hope this helps someone!

.