Gradle release build with proguard: java.lang.IncompatibleClassChangeError and java.lang.NoSuchMethodError

StackOverflow https://stackoverflow.com/questions/22393406

سؤال

I recently migrated a project from Eclipse/Ant to Android Studio/Gradle. I am able to successfully build a signed release version of the project with proguard enabled. However, while testing the release version, I'm getting crashes from certain library projects and jars (which work fine when building a debug version).

For example, when attempting to upload a file to Dropbox (a jar dependency), I get the following error:

java.lang.IncompatibleClassChangeError: interface not implemented
   at com.dropbox.client2.session.AbstractSession.sign(SourceFile:238)
   at com.dropbox.client2.DropboxAPI.putFileRequest(SourceFile:2199)
   at com.dropbox.client2.DropboxAPI.putFileOverwriteRequest(SourceFile:1571)
   at com.dropbox.client2.DropboxAPI.putFileOverwrite(SourceFile:1537)

Also, when attempting to sign into Box (a library project dependency), I get the following error:

java.lang.NoSuchMethodError: org.apache.http.conn.params.ConnManagerParams.setMaxTotalConnections
   at com.box.restclientv2.BoxBasicRestClient.()
   at com.box.boxjavalibv2.BoxRESTClient.()
   at com.box.boxjavalibv2.BoxClient.createRestClient()
   at com.box.boxjavalibv2.BoxClient.()
   at com.box.boxandroidlibv2.BoxAndroidClient.(SourceFile:49)
   at com.box.boxandroidlibv2.activities.OAuthActivity.startOAuth(SourceFile:71)
   at com.box.boxandroidlibv2.activities.OAuthActivity.onCreate(SourceFile:52)

I have other jars and library projects that work just fine...

Again, there are no issues with either of these when building a gradle debug build (no proguard). I was also able to create a release build with proguard enabled using ant without any issues (able to sign into both Dropbox and Box).

Any ideas?

هل كانت مفيدة؟

المحلول

You appear to be including a version of the org.apache.http library. In principle, this library is already part of the Android runtime android.jar, so you shouldn't add it to your project. ProGuard is probably printing warnings about these duplicate classes.

In practice, it may be a newer version of the library, and some of your code may be using additional classes from this version. You then probably should leave the names of the classes, fields, and methods untouched, to avoid introducing (additional) conflicts:

-keep class org.apache.http.** { *; }

A build process may filter out the classes, or it may be adding the above line, but I don't think the default Android builds currently do either.

نصائح أخرى

You need to -keep Proguard from removing or renaming all the class and method names that it can't determine are referenced from code that it doesn't processes, that are referenced via reflection (e.g. XML references), etc.

Keeping all apache classes may keep more than necessary (which is OK) but it may not be enough to fix all the Proguard issues.

It's good to ask why it worked from your ant build without this -keep. Maybe the ant build didn't actually call Proguard (ant is tricky), maybe it used a different Proguard data file, or maybe the relevant libraries changed in the meantime. You can debug that by listing hypotheses and testing them. E.g. if you put a malformed command in the Proguard data file then run the ant build, you can tell whether it actually runs Proguard or not.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top