android中使用codec总是报NoSuchMethodError的问题根源
来源:互联网 发布:2016淘宝618报名 编辑:程序博客网 时间:2024/05/16 18:40
该问题在StackOverflow上有人给出了解决方案,但是更重要的是,下面有一个哥们给出了造成问题的原因分析!
原问题的地址是:http://stackoverflow.com/questions/9126567/method-not-found-using-digestutils-in-android
给出的问题解决方法是:
I ran into the same issue trying to use DigestUtils in my Android app. This was the best answer I could find by searching, but I was reluctant to rebuild the .jar file with the namespace changed. After spending some time on this issue, I found an easier way to solve the problem for my case. The problem statement for my code was
String s = DigestUtils.md5Hex(data);
Replace this statement with the following and it will work:
String s = new String(Hex.encodeHex(DigestUtils.md5(data)));
Similarly, for shaHex exampl, you can change it to
String hash = new String(Hex.encodeHex(DigestUtils.sha("textToHash");
This works because even though Android does not have encodeHexString(), it does have encodeHex(). Hope this would help others who run into the same issue.
然后底下纷纷有人留言疑惑虽然解决了问题,但是原因是啥?终于大神出现了,给出了他的回答:
Since there's no clear answer for the root cause of this problem, I'd like to clarify what's happening here.
Why the NoSuchMethodError is thrown in the first place?
According to exception stack trace, the line that causes the fault is 226 in DigestUtils#md5hex
method. Let's see what we have there (I'm assuming you have used version 1.4, since this is the only release whereHex#encodeHexString
method is being invoked in line 226):
public static String md5Hex(String data) { return Hex.encodeHexString(md5(data));}
The exception says java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Hex.encodeHexString
.Let's understand why.
First of all, Android framework already includes the Commons Codec
library (except theDigestUtils
class). Yes, it is not exposed as part of the Android SDK
and you cannot use it directly. But you still want to use it. So what you do? You addCommons Codec
library as part of your application. The compiler doesn't complain - from his point of view everything was fine.
But what happens at runtime? Let's follow your exception stack trace:
First, you're calling DigestUtils#md5Hex
from your Activity's onCreate
method. As I wrote above, the framework doesn't include that class, soDigestUtils
(from Commons Codec
version 1.4) is loaded from your dex.
Next, md5hex
method tries to invoke Hex#encodeHexString
method.Hex
class is part of the Commons Codec
library that included in framework. The thing is that its version is1.3 (ancient release from July 2004). Hex
class exists in boot classpath, which means that the runtime will always favor it instead of theHex
class that packaged inside your dex. You can see warnings about it in your application logs when you start your app (with Dalvik runtime):
D/dalvikvm? DexOpt: 'Lorg/apache/commons/codec/binary/Hex;' has an earlier definition; blocking outI/dalvikvm? DexOpt: not resolving ambiguous class 'Lorg/apache/commons/codec/binary/Hex;'D/dalvikvm? DexOpt: not verifying/optimizing 'Lorg/apache/commons/codec/binary/Hex;': multiple definitionsI/dalvikvm? Could not find method org.apache.commons.codec.binary.Hex.encodeHexString, referenced from method org.apache.commons.codec.digest.DigestUtils.md5Hex
Hex#encodeHexString method was introduced in version 1.4 ofCommons Codec
library and therefore it doesn't exist in framework's Hex
class. The runtime can't find this method and thus throws NoSuchMethodError
exception.
Why the accepted answer's solution works?
String s = new String(Hex.encodeHex(DigestUtils.md5(data)));
First, DigestUtils#md5
method is called. As I already stated, DigestUtils
class that will be used is the one that packaged in your dex. This method doesn't use any otherCommons Codec
classes, so no problem with it.
Next, Hex#encodeHex
will be called. The Hex
class that will be used is the framework's one (version 1.3). TheencodeHex
method (that takes a single parameter - byte array) exists in version 1.3 ofCommons Codec
library, and therefore this code will work fine.
What would I suggest?
My suggested solution is to rename the classes namespace/package. By doing so I'm explicitly specifying which code is going to execute, and prevent bizarre behavior that may occur because of versioning issues.
You can do it manually (as Caumons wrote in his answer), or automatically withjarjar tool.
See this issue summary and tips for using jarjar
in my blogpost.
- android中使用codec总是报NoSuchMethodError的问题根源
- Android 使用RecyclerView 报错NoSuchMethodError
- 使用Guava报错NoSuchMethodError的解决方法
- 使用Guava报错NoSuchMethodError的解决方法
- Android使用commons-codec-1.6 遇到的问题
- android 129 133问题根源
- spring boot 报错:Exception in thread "main" java.lang.NoSuchMethodError 根源在pom.xml引用的包中的JAR有冲突
- 报nosuchMethodError错误的总结
- 关于PLSQL本地连接总是报错的问题
- 项目在总是报mysql表不存在的问题
- 问题根源
- 解决Android工程中引入codec.jar包报错问题
- 安卓listview两个类型条目的复用,总是报数组越界Android listview ArrayIndexOutOfBoundsException问题
- weblogic中使用commons-lang包报java.lang.NoSuchMethodError解决办法
- 关于使用google map程序中报java.lang.NoClassDefFoundError: android.net.NetworkConnectivityListener的问题
- 关于android开发中使用系统权限报错的问题
- Android使用AIDL实现进程通信中Service报错的问题
- 关于Android studio 使用aar 文件中引用了其他aar文件报错的问题
- 虚函数表历险记
- LA 4287(p322)----Proving Equivalences
- hdu 4777 树状数组+合数分解
- SQL Server 2008还原数据库时出现“备份集中的数据库备份与现有的数据库不同”的解决方法
- 哈希表
- android中使用codec总是报NoSuchMethodError的问题根源
- 简单选择排序
- 2015年12月27日
- DOM(文档对象模型节点)
- 一个简单的有限状态机例子
- codeforces Kojiro and Furrari
- C++primer plus 编程练习10.10
- [BZOJ 3575] HNOI2014 道路堵塞
- 移动端尺寸基础知识