java - Proguard 提示外部 JAR 中缺少类。如何正确解决这个问题?

标签 java android eclipse proguard

我正在尝试混淆在 Eclipse 中使用 Dropbox 和 Proguard 的 Android 4+ 应用程序。到目前为止,我没有使用 Proguard 的经验,因此我在 SO 上使用了不同的教程和答案来配置我的 proguard-project.txt:

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

当我尝试使用 File/Export.../Export Android Application/... 对话框导出 APK 时,创建失败并出现 Proguard 错误:

[2014-08-29 09:50:30 - MyApp] Proguard returned with error code 1. See console
[2014-08-29 09:50:30 - MyApp] Note: there were 367 duplicate class definitions.
[2014-08-29 09:50:30 - MyApp] Warning: org.apache.commons.logging.impl.ServletContextCleaner: can't find superclass or interface javax.servlet.ServletContextListener
[2014-08-29 09:50:30 - MyApp] Warning: org.apache.http.entity.mime.FormBodyPart: can't find superclass or interface org.apache.james.mime4j.message.BodyPart
...
[2014-08-29 09:50:30 - MyApp] Warning: library class android.net.http.AndroidHttpClient extends or implements program class org.apache.http.client.HttpClient
...
[2014-08-29 09:50:30 - MyApp] Warning: org.bouncycastle.x509.util.LDAPStoreHelper: can't find referenced class javax.naming.directory.DirContext
[2014-08-29 09:50:30 - MyApp]       You should check if you need to specify additional program jars.
[2014-08-29 09:50:30 - MyApp] Warning: there were 223 unresolved references to classes or interfaces.
[2014-08-29 09:50:30 - MyApp]          You may need to specify additional library jars (using '-libraryjars').
[2014-08-29 09:50:30 - MyApp] Warning: there were 1 instances of library classes depending on program classes.
[2014-08-29 09:50:30 - MyApp]          You must avoid such dependencies, since the program classes will
[2014-08-29 09:50:30 - MyApp]          be processed, while the library classes will remain unchanged.
[2014-08-29 09:50:30 - MyApp] Warning: there were 13 unresolved references to program class members.
[2014-08-29 09:50:30 - MyApp]          Your input classes appear to be inconsistent.
[2014-08-29 09:50:30 - MyApp]          You may need to recompile them and try again.
[2014-08-29 09:50:30 - MyApp]          Alternatively, you may have to specify the option 
[2014-08-29 09:50:30 - MyApp]          '-dontskipnonpubliclibraryclassmembers'.
[2014-08-29 09:50:30 - MyApp] java.io.IOException: Please correct the above warnings first.
[2014-08-29 09:50:30 - MyApp]   at proguard.Initializer.execute(Initializer.java:321)
[2014-08-29 09:50:30 - MyApp]   at proguard.ProGuard.initialize(ProGuard.java:211)
[2014-08-29 09:50:30 - MyApp]   at proguard.ProGuard.execute(ProGuard.java:86)
[2014-08-29 09:50:30 - MyApp]   at proguard.ProGuard.main(ProGuard.java:492) 

我尝试的第一件事是添加一些 -libraryjars ... 命令:

-libraryjars 'F:/Path/To/Workspace/Third Party/Dropbox/dropbox-android-sdk-1.6.1/lib/bcprov-jdk16-146.jar'
-libraryjars 'F:/Path/To/Workspace/Third Party/Dropbox/dropbox-android-sdk-1.6.1/lib/commons-logging-1.1.1.jar'
-libraryjars 'F:/Path/To/Workspace/Third Party/Dropbox/dropbox-android-sdk-1.6.1/lib/dropbox-android-sdk-1.6.1.jar'
-libraryjars 'F:/Path/To/Workspace/Third Party/Dropbox/dropbox-android-sdk-1.6.1/lib/httpclient-4.0.3.jar'
-libraryjars 'F:/Path/To/Workspace/Third Party/Dropbox/dropbox-android-sdk-1.6.1/lib/httpcore-4.0.1.jar'
-libraryjars 'F:/Path/To/Workspace/Third Party/Dropbox/dropbox-android-sdk-1.6.1/lib/httpmime-4.0.3.jar'
-libraryjars 'F:/Path/To/Workspace/Third Party/Dropbox/dropbox-android-sdk-1.6.1/lib/json_simple-1.1.jar'

这并没有解决问题。事实上现在有 2468 个重复的类定义(之前有 367 个...)

接下来我尝试忽略警告:

-dontwarn org.bouncycastle.** 
-dontwarn org.apache.** 

问题解决了! APK 的创建现在运行时没有任何错误。好吧……但我对此没有什么好感。 忽略警告真的是解决此问题的最佳方法吗?这是处理此类问题的“正确”方法吗?

当我在我的设备上运行 APK 并尝试使用 Dropbox 功能时,应用程序崩溃了。但这可以通过添加以下内容来解决:

-keep class org.** { *; }
-keep class com.dropbox.** {*;}

这可以防止 Dropbox 代码被混淆。但我再次不确定这是否是处理此问题的正确方法。

到目前为止,该应用程序似乎可以在此配置下正常运行。但是有什么方法可以确保 Proguard 没有破坏任何东西(除了在每次创建应用程序时对每个应用程序功能运行完整的 Beta 测试之外?)

非常感谢!

最佳答案

您的第 3 方库被处理了两次。在本例中将它们添加到另一个文件夹 lib 并将以下行添加到 proguard.cfg 文件。

 -injars lib/dropbox.jar 

参见 Pro Guard Troubleshooting

Note: duplicate definition of program/library class

Your program jars or library jars contain multiple definitions of the listed classes. ProGuard continues processing as usual, only considering the first definitions. The warning may be an indication of some problem though, so it's advisable to remove the duplicates. A convenient way to do so is by specifying filters on the input jars or library jars. You can switch off these notes by specifying the -dontnote option.

ProGuard Troubleshooting page 的链接所示在您的控制台日志中,您应该将 project.properties 中的目标更改为包含缺失类的目标。在这种情况下:“android-18”或“Google Inc.:Google APIs:18”。

您仍然可以在 AndroidManifest.xml 中指定不同的 minSdkVersion。

您不应该指定任何 -libraryjars 选项,因为 Android 构建过程已经为您指定了这些选项——您现在只会看到有关重复类的警告。事实上,Android 构建过程还为您指定了大多数其他选项。

关于java - Proguard 提示外部 JAR 中缺少类。如何正确解决这个问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25564233/

相关文章:

java - MVC 架构中的 Rx

java - SWT-浏览器 : How to load a resource using HTTPS if the certificate is untrusted?

java - 局域网上的点对点发现

android - AsyncTask onPostExecute 不会返回到上一个 Activity

python - 当 Eclipse PyUnit Test Runner 配置为使用 Nose 时,控制台输出去哪里

java - 在 jar 中列出并加载类

android - 如何滑动和滚动到 Appium 中的最后一个

android - fragment onCreateView 和 onActivityCreated 调用了两次

eclipse - Photran 在 Eclipse 中创建 Fortran 项目时显示 "At least one configuration should be available. Project cannot be created."

java - 如何扫描数组并将输入与数组元素进行比较