From 85e21bd534d38f8de12e8229865a863f32c30e7a Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 25 Nov 2014 11:18:43 -0800 Subject: Mention ProGuard in the JNI documentation. (cherry picked from commit 8e1bbfe0f1e4dac35b20972a71656e4c9bf437a1) Change-Id: I22731dfb94dcc1271b987ed52914e665704dd378 --- docs/html/training/articles/perf-jni.jd | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/docs/html/training/articles/perf-jni.jd b/docs/html/training/articles/perf-jni.jd index 1a40f6237679..5a9fa1e04b46 100644 --- a/docs/html/training/articles/perf-jni.jd +++ b/docs/html/training/articles/perf-jni.jd @@ -635,20 +635,31 @@ avoid some problems.

FAQ: Why didn't FindClass find my class?

+

(Most of this advice applies equally well to failures to find methods +with GetMethodID or GetStaticMethodID, or fields +with GetFieldID or GetStaticFieldID.)

+

Make sure that the class name string has the correct format. JNI class names start with the package name and are separated with slashes, such as java/lang/String. If you're looking up an array class, you need to start with the appropriate number of square brackets and must also wrap the class with 'L' and ';', so a one-dimensional array of -String would be [Ljava/lang/String;.

+String would be [Ljava/lang/String;. +If you're looking up an inner class, use '$' rather than '.'. In general, +using javap on the .class file is a good way to find out the +internal name of your class.

+ +

If you're using ProGuard, make sure that +ProGuard didn't +strip out your class. This can happen if your class/method/field is only +used from JNI.

If the class name looks right, you could be running into a class loader issue. FindClass wants to start the class search in the class loader associated with your code. It examines the call stack, which will look something like:

    Foo.myfunc(Native Method)
-    Foo.main(Foo.java:10)
-    dalvik.system.NativeStart.main(Native Method)
+ Foo.main(Foo.java:10)

The topmost method is Foo.myfunc. FindClass finds the ClassLoader object associated with the Foo @@ -656,12 +667,9 @@ class and uses that.

This usually does what you want. You can get into trouble if you create a thread yourself (perhaps by calling pthread_create -and then attaching it with AttachCurrentThread). -Now the stack trace looks like this:

-
    dalvik.system.NativeStart.run(Native Method)
- -

The topmost method is NativeStart.run, which isn't part of -your application. If you call FindClass from this thread, the +and then attaching it with AttachCurrentThread). Now there +are no stack frames from your application. +If you call FindClass from this thread, the JavaVM will start in the "system" class loader instead of the one associated with your application, so attempts to find app-specific classes will fail.

-- cgit v1.2.3-59-g8ed1b