Moving from
class MostVisitedSites {
interface Observer { ... }
private native void nativeSetObserver(long nativeMostVisitedSites, Observer observer, ...);
}
To
interface MostVisitedSites {
interface Observer { ... }
}
class MostVisitedSitesBridge implements MostVisitedSites {
interface Observer { ... }
private native void nativeSetObserver(long nativeMostVisitedSites, Observer observer, ...);
}
The code above compiles but crashes at runtime:
D/dalvikvm: Trying to load lib /data/data/org.chromium.chrome/incremental-install-files/lib/libchrome.cr.so 0x425eeb18
D/dalvikvm: Added shared lib /data/data/org.chromium.chrome/incremental-install-files/lib/libchrome.cr.so 0x425eeb18
E/dalvikvm: ERROR: couldn't find native method
E/dalvikvm: Requested: Lorg/chromium/chrome/browser/suggestions/MostVisitedSitesBridge;.nativeSetObserver:(JLorg/chromium/chrome/browser/suggestions/Observer;I)V
E/dalvikvm: Candidate: Lorg/chromium/chrome/browser/suggestions/MostVisitedSitesBridge;.nativeSetObserver:(JLorg/chromium/chrome/browser/suggestions/MostVisitedSites$Observer;I)V
E/chromium: [0317/154432.314259:ERROR:jni_generator_helper.h(38)] RegisterNatives failed in gen/chrome/browser/jni_headers/chrome/jni/MostVisitedSitesBridge_jni.h
E/chromium: [0317/154432.314376:ERROR:jni_registrar.cc(21)] MostVisitedSitesBridge failed registration!
W/dalvikvm: threadid=13: thread exiting with uncaught exception (group=0x41591ba8)
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #3
E/AndroidRuntime: Process: org.chromium.chrome, PID: 18657
E/AndroidRuntime: java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime: at android.os.AsyncTask$3.done(AsyncTask.java:300)
E/AndroidRuntime: at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
E/AndroidRuntime: at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
E/AndroidRuntime: at java.util.concurrent.FutureTask.run(FutureTask.java:242)
E/AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
E/AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
E/AndroidRuntime: at java.lang.Thread.run(Thread.java:841)
E/AndroidRuntime: Caused by: java.lang.NoSuchMethodError: no static or non-static method "Lorg/chromium/chrome/browser/suggestions/MostVisitedSitesBridge;.nativeSetObserver(JLorg/chromium/chrome/browser/suggestions/Observer;I)V"
E/AndroidRuntime: at java.lang.Runtime.nativeLoad(Native Method)
I tried changing the native method declaration to use a qualified class name
private native void nativeSetObserver(long nativeMostVisitedSites, MostVisitedSites.Observer observer, ...);
That fails at compile time:
Working directory: /usr/local/ssd/clankium/src
ninja -j2000 -l150 -C out_android_gn/Debug chrome_public_apk_incremental
ninja: Entering directory `out_android_gn/Debug'
[2/105] ACTION //chrome/browser:jni_headers__jni_gen(//build/toolchain/android:android_clang_arm)
FAILED: gen/chrome/browser/jni_headers/chrome/jni/MostVisitedSitesBridge_jni.h
python ../../base/android/jni_generator/jni_generator.py --depfile gen/chrome/browser/jni_headers__jni_gen.MostVisitedSitesBridge.d --input_file=../../chrome/android/java/src/org/chromium/chrome/browser/suggestions/MostVisitedSitesBridge.java --optimize_generation=1 --ptr_type=long --output_dir gen/chrome/browser/jni_headers/chrome/jni --includes ../../../../../../../../base/android/jni_generator/jni_generator_helper.h --native_exports_optional
Traceback (most recent call last):
File "../../base/android/jni_generator/jni_generator.py", line 1418, in <module>
sys.exit(main(sys.argv))
File "../../base/android/jni_generator/jni_generator.py", line 1411, in main
GenerateJNIHeader(input_file, output_file, options)
File "../../base/android/jni_generator/jni_generator.py", line 1318, in GenerateJNIHeader
input_file, options)
File "../../base/android/jni_generator/jni_generator.py", line 720, in CreateFromFile
return JNIFromJavaSource(contents, fully_qualified_class, options)
File "../../base/android/jni_generator/jni_generator.py", line 692, in __init__
self.content = inl_header_file_generator.GetContent()
File "../../base/android/jni_generator/jni_generator.py", line 788, in GetContent
'JNI_NATIVE_METHODS': self.GetJNINativeMethodsString(),
File "../../base/android/jni_generator/jni_generator.py", line 861, in GetJNINativeMethodsString
return self.SubstituteNativeMethods(template)
File "../../base/android/jni_generator/jni_generator.py", line 844, in SubstituteNativeMethods
kmethods = self.GetKMethodsString(clazz)
File "../../base/android/jni_generator/jni_generator.py", line 835, in GetKMethodsString
ret += [self.GetKMethodArrayEntry(native)]
File "../../base/android/jni_generator/jni_generator.py", line 1183, in GetKMethodArrayEntry
True),
File "../../base/android/jni_generator/jni_generator.py", line 343, in Signature
items += [JniParams.JavaToJni(param.datatype) for param in params]
File "../../base/android/jni_generator/jni_generator.py", line 312, in JavaToJni
outer.replace('/', '.')))
SyntaxError: Inner class (MostVisitedSites.Observer) can not be used directly by JNI. Please import the outer class, probably:
import org.chromium.chrome.browser.suggestions.MostVisitedSites;
[4/105] ACTION //chrome/android:chrome_java__compile_java__javac(//build/toolchain/android:android_clang_arm)
My current workaround is to just declare the parameter as Object, but keeping the relative type safety would be preferred, or at least for documentation purposes. Can this be fixed in the generator?
CL for context: https://codereview.chromium.org/2754203004
Comment 1 by dgn@chromium.org
, Mar 20 2017