views:

877

answers:

2

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.

+4  A: 

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('/','_');

Hope that helps!

Pablo Fernandez
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 -
jax
I guess it doesn't matter, you would do just the same as the example above
Pablo Fernandez
A: 

I have exactly the same problem. I think Pablo's suspicion about Android including an earlier version of Commons Codec is spot on. This is an extract from the logcat output that I initially did not notice because it happens on deployment rather than at runtime:

D/dalvikvm(  345): DexOpt: 'Lorg/apache/commons/codec/binary/Base64;' has an earlier definition; blocking out
D/dalvikvm(  345): DexOpt: 'Lorg/apache/commons/codec/binary/BinaryCodec;' has an earlier definition; blocking out
D/dalvikvm(  345): DexOpt: 'Lorg/apache/commons/codec/binary/Hex;' has an earlier definition; blocking out
D/dalvikvm(  345): DexOpt: 'Lorg/apache/commons/codec/language/DoubleMetaphone$DoubleMetaphoneResult;' has an earlier definition; blocking out
D/dalvikvm(  345): DexOpt: 'Lorg/apache/commons/codec/language/DoubleMetaphone;' has an earlier definition; blocking out
D/dalvikvm(  345): DexOpt: 'Lorg/apache/commons/codec/language/Metaphone;' has an earlier definition; blocking out
D/dalvikvm(  345): DexOpt: 'Lorg/apache/commons/codec/language/RefinedSoundex;' has an earlier definition; blocking out
D/dalvikvm(  345): DexOpt: 'Lorg/apache/commons/codec/language/Soundex;' has an earlier definition; blocking out
D/dalvikvm(  345): DexOpt: 'Lorg/apache/commons/codec/language/SoundexUtils;' has an earlier definition; blocking out
D/dalvikvm(  345): DexOpt: 'Lorg/apache/commons/codec/net/RFC1522Codec;' has an earlier definition; blocking out
D/dalvikvm(  345): DexOpt: 'Lorg/apache/commons/codec/net/BCodec;' has an earlier definition; blocking out
D/dalvikvm(  345): DexOpt: 'Lorg/apache/commons/codec/net/QCodec;' has an earlier definition; blocking out
D/dalvikvm(  345): DexOpt: 'Lorg/apache/commons/codec/net/QuotedPrintableCodec;' has an earlier definition; blocking out
D/dalvikvm(  345): DexOpt: 'Lorg/apache/commons/codec/net/URLCodec;' has an earlier definition; blocking out
I/dalvikvm(  345): DexOpt: not resolving ambiguous class 'Lorg/apache/commons/codec/binary/Base64;'
D/dalvikvm(  345): DexOpt: not verifying 'Lorg/apache/commons/codec/Decoder;': multiple definitions

I'm not quite sure where these Commons Codec classes come from. Unlike the Commons HTTP classes, they are not included in the Android API docs or in android.jar.

Two questions remain:

  1. Is there a list somewhere of libraries that are included in this way and therefore might cause problems?
  2. Is it safe to rely on the presence of such libraries?
Dan Dyer