ClassNotFoundException when finding a class in JNI background thread

Viewed 1937

My Android app gives me a ClassNotFoundException when I try to create an ArrayList on a background thread in my C++ code.

In JNI_OnLoad() I stash aside my class loader:

jclass clsMine = env->FindClass("com/mypackage/MyClass");
jclass classClass = env->GetObjectClass(clsMine);
jclass classLoaderClass = env->FindClass("java/lang/ClassLoader");
jmethodID getClassLoaderMethod = env->GetMethodID(classClass, "getClassLoader", "()Ljava/lang/ClassLoader;");
gClassLoader = env->NewGlobalRef(env->CallObjectMethod(clsMine, getClassLoaderMethod));
gFindClassMethod = env->GetMethodID(classLoaderClass, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;");

I have a findClass() method which I can call from other threads:

static jclass findClass(JNIEnv* env, const char* name)
{
    return static_cast<jclass>(env->CallObjectMethod(gClassLoader, gFindClassMethod, env->NewStringUTF(name)));
}

I can use this to get access to MyClass and its inner classes and interfaces. But when I try to create an ArrayList, my findClass() throws a ClassNotFoundException.

I realized that if my Java code creates an ArrayList before I load my native library, then I don't get an exception. Or if I env->FindClass("java/util/ArrayList") in JNI_OnLoad() then I don't get an exception. But these are work-arounds. Why can't I create Java classes using the class loader I stashed aside? Or should I be using a different class loader?

EDIT:

And to add a wrinkle, under ART my work-around to call env->FindClass("java/util/ArrayList") in JNI_OnLoad() doesn't work.

0 Answers
Related