Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

StackOverflow Point

StackOverflow Point Navigation

  • Web Stories
  • Badges
  • Tags
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Web Stories
  • Badges
  • Tags
Home/ Questions/Q 228110
Next
Alex Hales
  • 0
Alex HalesTeacher
Asked: July 31, 20222022-07-31T05:38:33+00:00 2022-07-31T05:38:33+00:00In: Android, Apache, digest, encryption, sha

apache – Method not found using DigestUtils in Android

  • 0

[ad_1]

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 where Hex#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 the DigestUtils 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 add Commons 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, so DigestUtils (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 is 1.3 (ancient release from July 2004). Hex class exists in boot classpath, which means that the runtime will always favor it instead of the Hex 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 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

Hex#encodeHexString method was introduced in version 1.4 of Commons 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 other Commons 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). The encodeHex method (that takes a single parameter – byte array) exists in version 1.3 of Commons 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 with jarjar tool.

See this issue summary and tips for using jarjar in my blogpost.

[ad_2]

  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report
Leave an answer

Leave an answer
Cancel reply

Browse

Sidebar

Ask A Question

Related Questions

  • xcode - Can you build dynamic libraries for iOS and ...

    • 0 Answers
  • bash - How to check if a process id (PID) ...

    • 5380 Answers
  • database - Oracle: Changing VARCHAR2 column to CLOB

    • 1169 Answers
  • What's the difference between HEAD, working tree and index, in ...

    • 1111 Answers
  • Amazon EC2 Free tier - how many instances can I ...

    • 0 Answers

Stats

  • Questions : 43k

Subscribe

Login

Forgot Password?

Footer

Follow

© 2022 Stackoverflow Point. All Rights Reserved.

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.