When attempting to write Substrate extensions that modify the behavior of existing Java code, one often runs into the problem that large amounts of functionality have been marked with any of private, protected, or final, making it impossible to easily call into, access, or subclass anything using Java.
While JNI does not have these access restrictions (and is thereby able to call any method or access any field), JNI is "irritatingly low-level and verbose": what might be one or two lines of code in Java might require looking up 10 method/field identifiers and crossing the costly JNI boundary for each call.
Instead, it would be highly convenient to grant specific and limited amounts of code access to the same freedoms that we have when using JNI. Substrate exposes this functionality by allowing developers to "bless" a Java ClassLoader instance, claiming that all code it loads should be considered omniscient.
Obviously, this API is not useful without a way to generate class files that would not normally verify, something that the normal javac is explicitly designed to avoid. Therefore, a solution to this problem is shipped with the Substrate SDK. For more information, read our guide on Java Access Control.
See also: Wikileaks To Leak 5000 Open Source Java Projects With All That Private/Final Bullshit Removed
void MSJavaBlessClassLoader(JNIEnv *jni, jobject loader);
Parameter | Description |
---|---|
jni |
JNI environment used to interpret loader argument. |
loader |
JNI reference to class loader that will be blessed. |
JNIEnv *jni = /* ... */; jobject object = /* get Android Context */; jobject loader; loader = jni->CallObjectMethod(object, jni->GetMethodID( jni->GetObjectClass(object), // android.content.Context "getClassLoader", "()Ljava/lang/ClassLoader;"); )); MSJavaBlessClassLoader(jni, loader);