Proguard的引发NoSuchMethodException - 随访 [英] Proguard causing NoSuchMethodException - followup

查看:184
本文介绍了Proguard的引发NoSuchMethodException - 随访的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

继@AlexWein在<一的建议href=\"http://stackoverflow.com/questions/16680813/proguard-causing-nosuchmethodexception/16690981\">this问题看着 ProGuard的故障排除的,我有以下在SherlockFragment:

 类&LT;&GT; C =的Class.forName(co.uk.MyApp.pdf.MyData);
方法主要= c.getDeclaredMethod(pdfsleep,Report_Holder.class);
Report_Holder paramsh = NULL;
paramsh = SRH;
main.invoke(NULL,(对象)paramsh);

co.uk.MyApp.pdf.Data构造函数是:

 公共类迈德特{
公共静态无效pdfsleep(Report_Holder参数){
...
}
}

Proguard的设置,像这样:

  -keepnames类co.uk.MyApp.classes.Report_Holder
-keepclassmembers类co.uk.MyApp.pdf.Data {公共静态无效pdfsleep(Report_Holder); }
-keepnames类co.uk.MyApp.DataActivity

但我仍然得到一个NoSuchMethodException:

  13年5月23日12点14分28秒GMT + 01:00错误的AsyncTask#2  -  java.lang.NoSuchMethodException:pdfsleep [类co.uk.MyApp.classes.Report_Holder ]
在java.lang.Class.getConstructorOrMethod(Class.java:460)
在java.lang.Class.getDeclaredMethod(Class.java:685)
在co.uk.MyApp.fy.a(来源不明)
在co.uk.MyApp.fy.doInBackground(来源不明)
在android.os.AsyncTask $ 2.call(AsyncTask.java:264)
在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:305)
在java.util.concurrent.FutureTask.run(FutureTask.java:137)
在android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:208)
在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:569)
在java.lang.Thread.run(Thread.java:856)

我是什么失踪?

更新

我Proguard的线路已更改为:

  -keepattributes签名
-keepnames类co.uk.MyApp.classes.Report_Holder
-keepclasseswithmembers类co.uk.MyApp.DataActivity
-keepclasseswithmembers类co.uk.MyApp.pdf.Data {无效pdfsleep(Report_Holder); }

和我仍然得到错误。

综观映射文件,我认为,我看是什么原因造成的问题:

  co.uk.MyApp.classes.Report_Holder  - &GT; co.uk.MyApp.classes.Report_Holder:co.uk.MyApp.DataActivity  - &GT; co.uk.MyApp.DataActivity:
java.util.ArrayList中arrDataItems - &GT;一个
co.uk.MyApp.classes.Report_Holder SRH - &GT; b

看起来Proguard的是保持参考co.uk.MyApp.classes.Report_Holder,但引用它作为co.uk.MyApp.DataActivity的孩子时,混淆了。

我试图保持co.uk.MyApp.DataActivity,试图让它停下混淆co.uk.MyApp.classes.Report_Holder不同的方式,但不能得到正确的语法。有什么建议?

更新2

我已经更新了一些code和ProGuard的配置文件由Eric Lafortune建议(顺便说一句,我现在显示正确的包/类名):

在co.uk.FibroApp.SleepDataActivity

 类&LT;&GT; C =的Class.forName(co.uk.FibroApp.pdf.SleepData);
方法主要= c.getDeclaredMethod(pdfsleep,co.uk.FibroApp.classes.Slee preport_Holder.class);斯利preport_Holder paramsh = SRH;

co.uk.FibroApp.pdf.SleepData是:

 公共类SleepData {
公共静态无效pdfsleep(co.uk.FibroApp.classes.Slee preport_Holder参数){
...
}
}

全部ProGuard的配置是:

  -keepattributes签名-keep类co.uk.FibroApp.classes.Slee preport_Holder
-keep类co.uk.FibroApp.pdf.SleepData
-keepclassmembers类co.uk.FibroApp.pdf.SleepData {
    公共静态无效pdfsleep(co.uk.FibroApp.classes.Slee preport_Holder);
}#不从droidtext混淆类,但其缩水
-keep,allowshrinking类harmony.java.awt ** {*。 }
-keep,allowshrinking类org.apache.harmony ** {*。 }
-keep,allowshrinking类org.bouncycastle ** {*。 }-keep类android.support.v4.app ** {*。 }
-keep接口android.support.v4.app ** {*。 }
-keep类com.actionbarsherlock ** {*。 }
-keep接口com.actionbarsherlock ** {*。 }-keepattributes *注释*

和完整的错误日志是:

  05/24/13 8时25分52秒WEST错误的AsyncTask#2  -  java.lang.NoSuchMethodException:sleeppdf [类co.uk.FibroApp.classes.Slee preport_Holder ]
在java.lang.Class.getConstructorOrMethod(Class.java:460)
在java.lang.Class.getDeclaredMethod(Class.java:685)
在co.uk.FibroApp.fy.a(来源不明)
在co.uk.FibroApp.fy.doInBackground(来源不明)
在android.os.AsyncTask $ 2.call(AsyncTask.java:264)
在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:305)
在java.util.concurrent.FutureTask.run(FutureTask.java:137)
在android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:208)
在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:569)
在java.lang.Thread.run(Thread.java:856)


解决方案

您code访问通过反射的方式方法。堆栈跟踪表明,ProGuard的已删除或重命名它。所以,你应该preserve它,用一条线就是你的code的头几乎直接复制:

  -keepclassmembers类co.uk.MyApp.pdf.MyData {
    公共静态无效pdfsleep(co.uk.MyApp.classes.Report_Holder);
}

ProGuard的识别的Class.forName构造并已preserves类MyData中。良好的措施,可以确保ProGuard的不删除类Report_Holder(应类恰好是未使用的,除了作为一个参数类型):

  -keep,allowobfuscation类co.uk.MyApp.classes.Report_Holder

注:


  • ProGuard文档资料介绍各种-keep选项之间的差异。如果你不知道,只是使用-keep。 (CFR)。用法> 概述保持选项


  • 您可能已经看到在您的控制台日志警告,Report_Holder必须与它的全名来指定。


Following the suggestions from @AlexWein in this question and looking at ProGuard Troubleshooting, I have the following in a SherlockFragment:

Class<?> c = Class.forName("co.uk.MyApp.pdf.MyData");
Method main = c.getDeclaredMethod("pdfsleep", Report_Holder.class);
Report_Holder paramsh = null;
paramsh = SRH;
main.invoke(null, (Object)paramsh);

"co.uk.MyApp.pdf.Data" constructor is:

public class MyData {
public static void pdfsleep(Report_Holder args) {
...
}
}

Proguard is set up like so:

-keepnames class co.uk.MyApp.classes.Report_Holder
-keepclassmembers class co.uk.MyApp.pdf.Data { public static void   pdfsleep(Report_Holder); }
-keepnames class co.uk.MyApp.DataActivity

But I am still getting a NoSuchMethodException:

05/23/13 12:14:28 GMT+01:00 ERROR  AsyncTask #2 - java.lang.NoSuchMethodException: pdfsleep [class co.uk.MyApp.classes.Report_Holder]
at java.lang.Class.getConstructorOrMethod(Class.java:460)
at java.lang.Class.getDeclaredMethod(Class.java:685)
at co.uk.MyApp.fy.a(Unknown Source)
at co.uk.MyApp.fy.doInBackground(Unknown Source)
at android.os.AsyncTask$2.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)

What am I missing?

Update

I have changed the Proguard lines to:

-keepattributes Signature
-keepnames class co.uk.MyApp.classes.Report_Holder
-keepclasseswithmembers class co.uk.MyApp.DataActivity 
-keepclasseswithmembers class co.uk.MyApp.pdf.Data { void pdfsleep(Report_Holder); }

And am still getting the error.

Looking at the mapping file, I think that I see what is causing the issue:

co.uk.MyApp.classes.Report_Holder -> co.uk.MyApp.classes.Report_Holder:

co.uk.MyApp.DataActivity -> co.uk.MyApp.DataActivity:
java.util.ArrayList arrDataItems -> a
co.uk.MyApp.classes.Report_Holder SRH -> b

It looks like Proguard is keeping the reference to co.uk.MyApp.classes.Report_Holder, but is obfuscating it when referencing it as a child of co.uk.MyApp.DataActivity.

I've tried different ways of keeping co.uk.MyApp.DataActivity, trying to get it to stop obfuscating co.uk.MyApp.classes.Report_Holder, but can't get the syntax correct. Any suggestions?

Update 2

I have updated some code and the ProGuard config file as suggested by Eric Lafortune (btw, I am showing proper package/classnames now):

In co.uk.FibroApp.SleepDataActivity

Class<?> c = Class.forName("co.uk.FibroApp.pdf.SleepData");
Method main = c.getDeclaredMethod("pdfsleep", co.uk.FibroApp.classes.SleepReport_Holder.class);

SleepReport_Holder paramsh = SRH;

co.uk.FibroApp.pdf.SleepData is:

public class SleepData {
public static void pdfsleep(co.uk.FibroApp.classes.SleepReport_Holder args) {
...
}
}

Full ProGuard config is:

-keepattributes Signature

-keep class co.uk.FibroApp.classes.SleepReport_Holder
-keep class co.uk.FibroApp.pdf.SleepData
-keepclassmembers class co.uk.FibroApp.pdf.SleepData {
    public static void pdfsleep(co.uk.FibroApp.classes.SleepReport_Holder);
}

# do not obfuscate the classes from droidtext but shrink them
-keep,allowshrinking class harmony.java.awt.** { *; }
-keep,allowshrinking class org.apache.harmony.** { *; }
-keep,allowshrinking class org.bouncycastle.** { *; }

-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class com.actionbarsherlock.** { *; }
-keep interface com.actionbarsherlock.** { *; }

-keepattributes *Annotation*

And the full error log is:

05/24/13 08:25:52 WEST ERROR  AsyncTask #2 - java.lang.NoSuchMethodException: sleeppdf [class co.uk.FibroApp.classes.SleepReport_Holder]
at java.lang.Class.getConstructorOrMethod(Class.java:460)
at java.lang.Class.getDeclaredMethod(Class.java:685)
at co.uk.FibroApp.fy.a(Unknown Source)
at co.uk.FibroApp.fy.doInBackground(Unknown Source)
at android.os.AsyncTask$2.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)

解决方案

Your code accesses a method by means of reflection. The stack trace indicates that ProGuard has removed or renamed it. So, you should preserve it, with a line that is almost a direct copy of the headers of your code:

-keepclassmembers class co.uk.MyApp.pdf.MyData {
    public static void pdfsleep(co.uk.MyApp.classes.Report_Holder);
}

ProGuard recognizes the Class.forName construct and already preserves the class MyData. For good measure, you can make sure ProGuard doesn't remove the class Report_Holder (should the class happen to be unused, other than as an argument type):

-keep,allowobfuscation class co.uk.MyApp.classes.Report_Holder

Notes:

  • The ProGuard documentation explains the differences between the various -keep options. If you're not sure, just use -keep. Cfr. Usage > Overview of Keep Options.

  • You may have seen a warning in your console log that Report_Holder has to be specified with its fully qualified name.

这篇关于Proguard的引发NoSuchMethodException - 随访的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆