57

Today I tried including the apache.commons.codec package in my Android application and couldn't get it running. Android could not find method ord.apache.commons.codec.binary.* and output the following errors in DDMS

01-12 08:41:48.161: ERROR/dalvikvm(457): Could not find method org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString, referenced from method com.dqminh.app.util.Util.sendRequest

01-12 08:41:48.161: WARN/dalvikvm(457): VFY: unable to resolve static method 10146: Lorg/apache/commons/codec/binary/Base64;.encodeBase64URLSafeString ([B)Ljava/lang/String;

01-12 08:41:48.161: WARN/dalvikvm(457): VFY: rejecting opcode 0x71 at 0x0004

Any clue on how to solve this problem ? Thanks a lot.

1
  • 3
    Have you got any of the Classes in apache.commons.codec working? So is it a peculiar problem with just this class or do you think none of the classes are available? Commented Jan 12, 2010 at 9:45

11 Answers 11

65

I had a similar problem while using android with an OAuth library I'm developing.

I also got from android that, although I had included apache.commons.codec in the classpath, a particular method (encodeBase64String) was not found.

Checking the javadocs, both methods claim to be 1.4 and greater only, so my guess is that android already includes an older version of commons.codec where these methods are indeed undefined.

My solution was to use an older method, like this:

String encodedString = new String(Base64.encodeBase64('string to encode')); 

The method you want to use is different since it replaces + and / with url-safe values - and _. So you probably might use something like:

String encodedString = new String(Base64.encodeBase64('string to encode')); String safeString = encodedString.replace('+','-').replace('/','_'); 
Sign up to request clarification or add additional context in comments.

2 Comments

I have been struggling with this for two days now! Just a question though, if I were to replace the + and - how would I go about decoding? What if the original encoded string (before the replacement) already contained + and -
I guess it doesn't matter, you would do just the same as the example above
18

You don't have to use apache commons, on android you can use android.util.Base64 instead.

4 Comments

Useful, but requires API level 8 (2.2.x).
Doesn't work if you are using a library that depends on Commons-Codec.
Be aware that you need to use Base64.encode("foobar".getBytes(), Base64.Base64.NO_WRAP); to get exactly the same result as the apache commons library. See: stackoverflow.com/questions/17912119
@DylanWatson: Thank you so much!!! I didn't set the "NO_WRAP" and that caused the issue in the communication of android-java and the "desktop" java-app I'm programming. Thanks!!
13

I experienced the exact same problem. So i started browsing the android source code, and as it turns out Pablo Fernandez's guess about Android having an implementation of org.apache.commons.code.binary is correct. However, its version 1.2 of the apache commons, not version 1.4 or even 1.5. You can see for your self in the android source.

as a note this is question is a duplicate of this post

1 Comment

The link for "Source" is broken. Could you fix that?
11

You can use the following function:

private static String encodeBase64URLSafeString(byte[] binaryData) { return android.util.Base64.encodeToString(binaryData, Base64.URL_SAFE); } 

source + listing of other possible flags: http://developer.android.com/reference/android/util/Base64.html

Comments

5

My solution to the same problem was to rename the problematic class org.apache.commons.codec.binary.Base64.java into org.apache.commons.codec.binary.ApacheBase64.java. I did it using Eclipse refactor-rename.

That way, the latest and greatest apache solution is preserved and used, and there is no chance for accidental problem recurrence when my app is eventually being lifted from android 1.6 lowest denominator.

Note I had the entire apache commons source tree already set as separate Eclipse java project, next to my Android project. My Android project used many of Apache Commons classes, but failed on Base64 because of above described problems...

1 Comment

I had the exact same issue with Hash, and was able to resolve it in a similar way (I actually refactored the package names for the entire Codec library).
5

You could simply copy this code bit from the apache library (it is pretty isolated) http://www.java2s.com/Open-Source/Android/Blog-Twitter/twitspeak/org/apache/commons/codec/binary/Base64.java.htm

Edit: Updated link from the Wayback Machine as the original is gone: http://web.archive.org/web/20130610025148/http://www.java2s.com/Open-Source/Android/Blog-Twitter/twitspeak/org/apache/commons/codec/binary/Base64.java.htm

Comments

3

Please note that this answer was made by Dylan Watson in the comments above:

Be aware that you need to use Base64.encode("foobar".getBytes(), Base64.Base64.NO_WRAP); to get exactly the same result as the apache commons library. See: stackoverflow.com/questions/17912119

This answer was the only which worked after hours of trying to communicate my android app with a java "desktop" app.

So here is some source code, maybe it will help others:

Code from the desktop applet:

 private static String convertToBase64(String s) { byte[] bytes = new byte[0]; try { bytes = (s.getBytes()); } catch (Exception e) { e.printStackTrace(); } return DatatypeConverter.printBase64Binary(bytes); } 

This snippet is used in the android app:

 public static String convertToBase64(String password) { byte[] bPwd = new byte[0]; try { bPwd = (password.getBytes("UTF-8")); } catch (Exception e) { e.printStackTrace(); } try { password = new String(Base64.encode(bPwd, Base64.NO_WRAP), "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return password; } 

1 Comment

Helped me a lot. Specially when using aws signature generating java class "SignedRequestsHelper" to sign url which uses "org.apache.commons.codec.binary.Base64". But in android we have to use "android.util.Base64" Had to replace "Base64 encoder = new Base64(); signature = new String(encoder.encode(rawHmac));" with "signature = new String(Base64.encode(rawHmac, Base64.NO_WRAP), "UTF-8");" to make it work. Elaborated comment is for future help seekers. May it help others. Thanks.....
3

You can simply import the following library under Gradle dependency

dependencies { implementation "commons-codec:commons-codec:1.11" } 

It will work

Comments

0

did you include apache commons project lib,like

org.apache.commons:commons-compress org.apache.commons:commons-email org.apache.commons:commons-io org.apache.commons:commons-lang3 org.apache.commons:commons-parent org.apache.commons:commons-pool2 

the commons-codec 's GAV is

commons-codec:commons-codec 

but it's package name is

org.apache.commons.codec 

this package name will be conflict with apache commons project libs,try to change the package name of commons-codec,then generate it as a jar or import the source code had changed the package name;

Comments

0

Knowing that this is an old question, but I faced this problem recently when compiling for API Level 23, and found another solution for the problem: use guava project.

// Encoding String encodedString = BaseEncoding.base64().encode(text.getBytes(UTF_8)); System.out.println("encodedString: " + encodedString); // Decoding byte[] decodedString = BaseEncoding.base64().decode(encodedString); System.out.println("decodedString: " + new String(decodedString, UTF_8)); 

The guava library (18.0) was the version that I've used, and the change was smooth. The code works as expected.

Solution found in here: https://memorynotfound.com/encode-decode-base64-string-using-native-java/

Comments

-1

This works for me:

import org.apache.commons.codec.binary.Base64; /** * This is used to get the base64 from the bytes * * @param rawBytes the raw bytes * @return the base64 encoded string */ public static String getBase64String(byte[] rawBytes) { String base64Str = ""; if (rawBytes!= null) { base64Str= new String(Base64.encodeBase64(rawBytes)); } return base64Str; } public static byte[] getBase64DecodedString(String base64EncodedStr) { byte[] base64Bytes = Base64.decodeBase64(base64EncodedStr.getBytes()); return bitmap; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.