Proguard 由于特定的第三方库而产生运行时错误

Posted

技术标签:

【中文标题】Proguard 由于特定的第三方库而产生运行时错误【英文标题】:Proguard produce runtime error because of specific third party library 【发布时间】:2016-07-23 06:33:51 【问题描述】:

最近我在android上完成了一个大项目,发布前的最后一个要求是它会在启用Proguard的情况下编译,我认为这将是项目中最容易的部分,但结果却是相当糟糕的经历对我来说。

在该项目中,我使用了几个第三方库,至少从我目前的检查来看,它们似乎都可以在我的 Proguard 配置中正常工作。

有问题的库是JWT: JSON Web Token for Java and Android,它没有关于如何使用 Proguard 配置它的文档,我尝试了很多不同的配置,但没有一个能解决这个问题。

只有当我将这一行放入代码中时才会出现错误(从这个库中调用一个类):

Jwts.builder();

而且报错如下:

java.lang.ExceptionInInitializerError 在 io.jsonwebtoken.Jwts.builder(ProGuard:116) 在 com.cineworld.app.screen_options.webpage.PurchaseWebPage.GenerateToken(ProGuard:216) 在 com.cineworld.app.screen_options.webpage.PurchaseWebPage.onCreateView(ProGuard:142) 在 android.app.Fragment.performCreateView(Fragment.java:1699) 在 android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885) 在 android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057) 在 android.app.BackStackRecord.run(BackStackRecord.java:682) 在 android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435) 在 android.app.FragmentManagerImpl$1.run(FragmentManager.java:441) 在 android.os.Handler.handleCallback(Handler.java:725) 在 android.os.Handler.dispatchMessage(Handler.java:92) 在 android.os.Looper.loop(Looper.java:137) 在 android.app.ActivityThread.main(ActivityThread.java:5041) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:511) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 在 dalvik.system.NativeStart.main(本机方法) 引起:java.lang.ExceptionInInitializerError 在 io.jsonwebtoken.impl.DefaultJwtBuilder.(ProGuard:42) 在 io.jsonwebtoken.Jwts.builder(ProGuard:116) 在 com.cineworld.app.screen_options.webpage.PurchaseWebPage.GenerateToken(ProGuard:216) 在 com.cineworld.app.screen_options.webpage.PurchaseWebPage.onCreateView(ProGuard:142) 在 android.app.Fragment.performCreateView(Fragment.java:1699) 在 android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885) 在 android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057) 在 android.app.BackStackRecord.run(BackStackRecord.java:682) 在 android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435) 在 android.app.FragmentManagerImpl$1.run(FragmentManager.java:441) 在 android.os.Handler.handleCallback(Handler.java:725) 在 android.os.Handler.dispatchMessage(Handler.java:92) 在 android.os.Looper.loop(Looper.java:137) 在 android.app.ActivityThread.main(ActivityThread.java:5041) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:511) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 在 dalvik.system.NativeStart.main(本机方法) 引起:java.lang.ExceptionInInitializerError 在 com.a.a.c.ad.(ProGuard:209) 在 io.jsonwebtoken.impl.DefaultJwtBuilder.(ProGuard:42) 在 io.jsonwebtoken.Jwts.builder(ProGuard:116) 在 com.cineworld.app.screen_options.webpage.PurchaseWebPage.GenerateToken(ProGuard:216) 在 com.cineworld.app.screen_options.webpage.PurchaseWebPage.onCreateView(ProGuard:142) 在 android.app.Fragment.performCreateView(Fragment.java:1699) 在 android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885) 在 android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057) 在 android.app.BackStackRecord.run(BackStackRecord.java:682) 在 android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435) 在 android.app.FragmentManagerImpl$1.run(FragmentManager.java:441) 在 android.os.Handler.handleCallback(Handler.java:725) 在 android.os.Handler.dispatchMessage(Handler.java:92) 在 android.os.Looper.loop(Looper.java:137) 在 android.app.ActivityThread.main(ActivityThread.java:5041) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:511) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 在 dalvik.system.NativeStart.main(本机方法) 引起:java.lang.NoSuchFieldError: PUBLIC_ONLY 在 java.lang.Class.getDeclaredAnnotation(本机方法) 在 java.lang.Class.getAnnotation(Class.java:260) 在 com.a.a.c.f.ac.(ProGuard:172) 在 com.a.a.c.ad.(ProGuard:209) 在 io.jsonwebtoken.impl.DefaultJwtBuilder.(ProGuard:42) 在 io.jsonwebtoken.Jwts.builder(ProGuard:116) 在 com.cineworld.app.screen_options.webpage.PurchaseWebPage.GenerateToken(ProGuard:216) 在 com.cineworld.app.screen_options.webpage.PurchaseWebPage.onCreateView(ProGuard:142) 在 android.app.Fragment.performCreateView(Fragment.java:1699) 在 android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885) 在 android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057) 在 android.app.BackStackRecord.run(BackStackRecord.java:682) 在 android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435) 在 android.app.FragmentManagerImpl$1.run(FragmentManager.java:441) 在 android.os.Handler.handleCallback(Handler.java:725) 在 android.os.Handler.dispatchMessage(Handler.java:92) 在 android.os.Looper.loop(Looper.java:137) 在 android.app.ActivityThread.main(ActivityThread.java:5041) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke

有人可以指导我处理这个问题的正确方法吗?

【问题讨论】:

【参考方案1】:

如果您想简单地防止整个 Java 包被混淆,因为找出出错的一件事太费时,请尝试将其添加到您的 proguard 规则文件中:

-keep class io.jsonwebtoken.** 
  public protected private *;

这些规则通常在项目的 proguard-rules.pro 文件中。

【讨论】:

这真是令人沮丧,这只是一个的事情,但无论我尝试什么,都没有任何效果。我添加了你的建议,但仍然发生崩溃,还尝试了不同的变体,如-keepclassmembers class io.jsonwebtoken.Jwts *; ,但同样,没有用,我不知道该怎么办,似乎错误来自特定函数返回 DefaultJwtBuilder 类型的新对象的库,你能帮我缩小问题的范围吗?我需要 Proguard 完全忽略这个库,但它似乎没有这样做...... Google 搜索“java PUBLIC_ONLY”发现这是第二次点击:***.com/questions/27184247/…

以上是关于Proguard 由于特定的第三方库而产生运行时错误的主要内容,如果未能解决你的问题,请参考以下文章

为啥切片长度大于容量会产生运行时错误?

Proguard 因 Google Play 服务库而失败

为啥在 Tornado 服务器 Post 方法中创建线程会产生运行时错误?

分配给 gslice_array 会产生运行时错误

使用公式连接引用会产生运行时错误

在机器级别上,应用程序以二进制形式运行,然后在发生运行时错误时,如何呈现回错误代码?