首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Android中使用DigestUtils找不到方法

在Android中使用DigestUtils找不到方法
EN

Stack Overflow用户
提问于 2012-02-03 17:43:11
回答 8查看 42.1K关注 0票数 83

我尝试使用JDK1.6在Android2.3.1中使用库DigestUtils,但在执行应用程序时遇到以下错误:

Could not find method org.apache.commons.codec.binary.Hex.encodeHexString, referenced from method org.apache.commons.codec.digest.DigestUtils.shaHex

下面是堆栈跟踪:

代码语言:javascript
复制
02-03 10:25:45.153: I/dalvikvm(1230): Could not find method org.apache.commons.codec.binary.Hex.encodeHexString, referenced from method org.apache.commons.codec.digest.DigestUtils.shaHex
02-03 10:25:45.153: W/dalvikvm(1230): VFY: unable to resolve static method 329: Lorg/apache/commons/codec/binary/Hex;.encodeHexString ([B)Ljava/lang/String;
02-03 10:25:45.153: D/dalvikvm(1230): VFY: replacing opcode 0x71 at 0x0004
02-03 10:25:45.153: D/dalvikvm(1230): VFY: dead code 0x0007-0008 in Lorg/apache/commons/codec/digest/DigestUtils;.shaHex ([B)Ljava/lang/String;
02-03 10:25:45.163: D/AndroidRuntime(1230): Shutting down VM
02-03 10:25:45.163: W/dalvikvm(1230): threadid=1: thread exiting with uncaught exception (group=0x40015560)
02-03 10:25:45.173: E/AndroidRuntime(1230): FATAL EXCEPTION: main
02-03 10:25:45.173: E/AndroidRuntime(1230): java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Hex.encodeHexString
02-03 10:25:45.173: E/AndroidRuntime(1230):     at org.apache.commons.codec.digest.DigestUtils.md5Hex(DigestUtils.java:226)
02-03 10:25:45.173: E/AndroidRuntime(1230):     at com.caumons.trainingdininghall.ConnectionProfileActivity.onCreate(ConnectionProfileActivity.java:20)
02-03 10:25:45.173: E/AndroidRuntime(1230):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-03 10:25:45.173: E/AndroidRuntime(1230):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1586)
02-03 10:25:45.173: E/AndroidRuntime(1230):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1638)
02-03 10:25:45.173: E/AndroidRuntime(1230):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
02-03 10:25:45.173: E/AndroidRuntime(1230):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:928)
02-03 10:25:45.173: E/AndroidRuntime(1230):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-03 10:25:45.173: E/AndroidRuntime(1230):     at android.os.Looper.loop(Looper.java:123)
02-03 10:25:45.173: E/AndroidRuntime(1230):     at android.app.ActivityThread.main(ActivityThread.java:3647)
02-03 10:25:45.173: E/AndroidRuntime(1230):     at java.lang.reflect.Method.invokeNative(Native Method)
02-03 10:25:45.173: E/AndroidRuntime(1230):     at java.lang.reflect.Method.invoke(Method.java:507)
02-03 10:25:45.173: E/AndroidRuntime(1230):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-03 10:25:45.173: E/AndroidRuntime(1230):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-03 10:25:45.173: E/AndroidRuntime(1230):     at dalvik.system.NativeStart.main(Native Method)

导致异常的代码行是:

String hash = DigestUtils.shaHex("textToHash");

我在Android外部的Java类中执行了相同的代码,并且它工作了!所以,我不知道为什么在使用Android的时候它不能工作…我把这个库放在我的应用程序中的一个新的库/文件夹中,并更新了BuildPath以使用它。如果我尝试使用md5而不是sha1,我会得到相同的异常。任何帮助都将不胜感激!谢谢。

更新:

由于这是一个非常活跃的问题,我已经改变了接受的答案,支持@DA25,因为他的解决方案很简单,大量的上榜证明它是有效的。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2012-02-15 04:59:01

我在我的安卓应用程序中使用DigestUtils时也遇到了同样的问题。这是我通过搜索所能找到的最好答案,但是我不愿意在名称空间发生变化的情况下重新构建.jar文件。在花了一些时间在这个问题上之后,我找到了一个更简单的方法来解决我的问题。我的代码的问题陈述是

代码语言:javascript
复制
String s = DigestUtils.md5Hex(data);

将此语句替换为以下语句,它将起作用:

代码语言:javascript
复制
String s = new String(Hex.encodeHex(DigestUtils.md5(data)));

类似地,对于shaHex示例,您可以将其更改为

代码语言:javascript
复制
String hash = new String(Hex.encodeHex(DigestUtils.sha("textToHash")));

这之所以有效,是因为即使安卓没有encodeHexString(),它也有encodeHex()。希望这能帮助其他遇到同样问题的人。

票数 151
EN

Stack Overflow用户

发布于 2015-04-24 03:55:38

由于这个问题的根本原因没有明确的答案,我想澄清这里发生了什么。

为什么首先抛出NoSuchMethodError?

根据异常堆栈跟踪,在DigestUtils#md5hex方法中导致错误的行是226。让我们看看我们有什么there (我假设您使用的是1.4版,因为这是在第226行调用Hex#encodeHexString方法的唯一版本):

代码语言:javascript
复制
public static String md5Hex(String data) {
    return Hex.encodeHexString(md5(data));
}

异常显示为java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Hex.encodeHexString。让我们来理解其中的原因。

首先,Android框架已经包含了Commons Codec库(除了DigestUtils类)。是的,它不会作为Android SDK的一部分公开,您不能直接使用它。但是你仍然想要使用它。那你是做什么的?将Commons Codec库添加为应用程序的一部分。编译器不会抱怨--从他的角度来看,一切都很好。

但是在运行时会发生什么呢?让我们跟踪您的异常堆栈跟踪:

首先,从活动的onCreate方法调用DigestUtils#md5Hex。正如我在上面所写的,框架不包含这个类,所以DigestUtils (来自Commons Codec版本1.4)是从您的dex加载的。

接下来,md5hex方法尝试调用Hex#encodeHexString方法。Hex类是框架中包含的Commons Codec库的一部分。问题是它的版本是1.3 (2004年7月的老版本)。Hex类存在于引导类路径中,这意味着运行时总是偏爱它,而不是打包在您的dex中的Hex类。当您启动应用程序(使用Dalvik运行时)时,您可以在您的应用程序日志中看到有关它的警告:

代码语言:javascript
复制
D/dalvikvm? DexOpt: 'Lorg/apache/commons/codec/binary/Hex;' has an earlier definition; blocking out
I/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 definitions
I/dalvikvm? Could not find method org.apache.commons.codec.binary.Hex.encodeHexString, referenced from method org.apache.commons.codec.digest.DigestUtils.md5Hex

Commons Codec库的1.4版本中引入了Hex#encodeHexString方法,因此它不存在于框架的Hex类中。运行库找不到此方法,因此抛出NoSuchMethodError异常。

为什么接受答案的解决方案有效?

代码语言:javascript
复制
String s = new String(Hex.encodeHex(DigestUtils.md5(data)));

首先,调用DigestUtils#md5方法。正如我已经说过的,将要使用的DigestUtils类是打包在您的dex中的类。此方法不使用任何其他Commons Codec类,因此使用它没有问题。

接下来,将调用Hex#encodeHex。将使用的Hex类是框架的类(1.3版)。Commons Codec库的1.3版本中存在encodeHex方法(只接受一个参数字节数组),因此这段代码可以很好地工作。

我该怎么建议呢?

我建议的解决方案是重命名类的名称空间/包。通过这样做,我显式地指定将执行哪些代码,并防止由于版本控制问题而可能发生的奇怪行为。

您可以手动完成(正如考蒙斯在他的答案中所写的那样),也可以使用jarjar工具自动完成。

请参阅此问题摘要和在my blogpost中使用jarjar的提示。

票数 37
EN

Stack Overflow用户

发布于 2012-02-04 19:11:00

最后我得到了答案,它工作得很好。正如在另一种类型的加密(Base64)的No such method error in Apache codec中所描述的,我尝试重现相同的问题,并且得到完全相同的错误。因此,我是在附加问题的情况下。正如他们所说,这似乎是内部名称与包名org.apache.commons.codec的冲突,正如@Don所说的那样,我将其更改为com.apache.commons.codec,并且工作正常!我是怎么做到的?

我下载了源代码,并将3个目录org更改为com。我还替换了出现包名称的文件中出现的所有内容,还将文档中的引用更改为com/apache/commons/codec/。(不要试图手动删除它们,否则您将花费一天的时间)。然后,我编译库并使用Ant生成jar,我将其命名为commons-codec-1.6-android.jar。我将jar放在我的安卓应用程序的libs/文件夹中,并将其添加到构建路径中。此外,我附加了源代码作为包含所有文件的文件夹。所以现在我已经准备好了这个库,可以在Android上使用了!

希望它能帮助其他人!

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9126567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档