使用proguard构建Gradle:java.lang.IncompatibleClassChangeError和java.lang.NoSuchMethodError

时间:2021-07-07 16:55:39

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).

我最近将项目从Eclipse / Ant迁移到Android Studio / Gradle。我能够在启用proguard的情况下成功构建项目的签名发布版本。但是,在测试发布版本时,我遇到了某些库项目和jar(在构建调试版本时工作正常)的崩溃。

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

例如,当尝试将文件上传到Dropbox(jar依赖项)时,我收到以下错误:

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:

此外,当尝试登录Box(库项目依赖项)时,我收到以下错误:

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).

同样,在构建gradle调试版本时没有任何问题(没有proguard)。我还能够创建一个发布版本,使用ant启用proguard,没有任何问题(能够登录Dropbox和Box)。

Any ideas?

有任何想法吗?

2 个解决方案

#1


4  

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.

您似乎包含org.apache.http库的一个版本。原则上,此库已经是Android运行时android.jar的一部分,因此您不应将其添加到项目中。 ProGuard可能会打印有关这些重复类的警告。

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.

构建过程可能会过滤掉类,或者它可能会添加上面的行,但我不认为默认的Android版本当前也会这样做。

#2


0  

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.

您需要 - 保持Proguard不会删除或重命名它无法确定的所有类和方法名称,这些名称是从它不处理的代码引用的,通过反射引用(例如XML引用)等。

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

保持所有apache类可能保持不必要(这没关系),但它可能不足以解决所有Proguard问题。

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.

很好地问你为什么它没有这个-keep你的蚂蚁构建工作。也许ant build实际上没有调用Proguard(ant很棘手),也许它使用了不同的Proguard数据文件,或者同时更改了相关的库。您可以通过列出假设并测试它们来调试它。例如。如果你在Proguard数据文件中输入格式错误的命令然后运行ant build,你可以判断它是否实际运行Proguard。

#1


4  

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.

您似乎包含org.apache.http库的一个版本。原则上,此库已经是Android运行时android.jar的一部分,因此您不应将其添加到项目中。 ProGuard可能会打印有关这些重复类的警告。

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.

构建过程可能会过滤掉类,或者它可能会添加上面的行,但我不认为默认的Android版本当前也会这样做。

#2


0  

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.

您需要 - 保持Proguard不会删除或重命名它无法确定的所有类和方法名称,这些名称是从它不处理的代码引用的,通过反射引用(例如XML引用)等。

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

保持所有apache类可能保持不必要(这没关系),但它可能不足以解决所有Proguard问题。

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.

很好地问你为什么它没有这个-keep你的蚂蚁构建工作。也许ant build实际上没有调用Proguard(ant很棘手),也许它使用了不同的Proguard数据文件,或者同时更改了相关的库。您可以通过列出假设并测试它们来调试它。例如。如果你在Proguard数据文件中输入格式错误的命令然后运行ant build,你可以判断它是否实际运行Proguard。