EpicPandaForce February 2016

Jasypt fails to initialize on Android 5.1.1 and above, ClassLoader is null

I was using Jasypt (compile 'org.jasypt:jasypt:1.9.2') normally with a Standard PBE encryptor

    StandardPBEByteEncryptor strongBinaryEncryptor = new StandardPBEByteEncryptor();
    strongBinaryEncryptor.setAlgorithm("...");
    strongBinaryEncryptor.setKeyObtentionIterations(...);
    strongBinaryEncryptor.setProviderName(BouncyCastleProvider.PROVIDER_NAME);
    strongBinaryEncryptor.setPassword("...");
    byte[] encryptedBytes = strongBinaryEncryptor.encrypt(bytes);

And this used to work without a problem, but now it crashes with the following root exception:

E/AndroidRuntime:  Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String)' on a null object reference
E/AndroidRuntime:     at org.jasypt.normalization.Normalizer.initializeIcu4j(Normalizer.java:139)
E/AndroidRuntime:     at org.jasypt.normalization.Normalizer.normalizeToNfc(Normalizer.java:96)
E/AndroidRuntime:     at org.jasypt.encryption.pbe.StandardPBEByteEncryptor.initialize(StandardPBEByteEncryptor.java:661)
E/AndroidRuntime:     at org.jasypt.encryption.pbe.StandardPBEByteEncryptor.encrypt(StandardPBEByteEncryptor.java:873) 

The same code works on Kitkat phone and the Lollipop emulator, but for example crashes on a OnePlusOne.

If you look at the source, what you see is this:

static void initializeIcu4j() throws ClassNotFoundException {        
    Thread.currentThread().getContextClassLoader().loadClass(ICU_NORMALIZER_CLASS_NAME);
    useIcuNormalizer = Boolean.TRUE;
}

Which means Thread.currentThread().getContextClassLoader() is null. This didn't use to happen, and I don't really know what caused this change in behavior. I also am not sure what I should do to fix it.

Any ideas?

Answers


EpicPandaForce February 2016

Based on a wiki page that has since been removed from Google Code, this actually used to be a bug in Dalvik as well, but a patch was commited in Froyo. However, ART seems to have resurfaced this exact same problem.

Apparently as per https://web.archive.org/web/20120303234738/http://code.google.com/p/dalvik/wiki/JavaxPackages the solution is to initialize the class loader manually in Activity.onCreate().

public class HelloStax extends Activity {
  @Override public void onCreate(Bundle savedInstanceState) {

    ...

    /*
     * Ensure the factory implementation is loaded from the application
     * classpath (which contains the implementation classes), rather than the
     * system classpath (which doesn't).
     */
    Thread.currentThread().setContextClassLoader(getClass().getClassLoader());

    ...
  }

Post Status

Asked in February 2016
Viewed 2,042 times
Voted 11
Answered 1 times

Search




Leave an answer