android 5.0 jni art,android art runtime check_jni.cc error on package name

问题

--EDIT--

i had too many versions of the shared lib floating around due to ambiguous build.gradle...

./src/main/jniLibs/armeabi-v7a/libaudioboo-native.so

rob@ app$ rm ./src/main/libs/armeabi-v7a/libaudioboo-native.so

rob@ app$ rm ./src/main/obj/local/armeabi-v7a/libaudioboo-native.so

rob@ app$ rm ./src/main/jniLibs/armeabi-v7a/libaudioboo-native.so

RESOLVED issue - changed build to the following to only use the shared lib in ./src/main/libs

sourceSets {

main {

jni.srcDirs = [] /*disable automatic ndk-build call */

jniLibs.srcDir 'src/main/libs'

}

}

Broke on android5 so i worked with it by tweeking it for Android-studio (1.0) ndk build. I scanned the code for all 'findClass' as pointed out by the answer @holo. Note - changed the string constant at line34 from

"fm.audioboo.jni.FLACStreamEncoder"; to "fm/audioboo/jni/FLACStreamEncoder";

That did not solve anything.

The java code calls a function and before that native function executes , it looks as tho the art framework on its own is calling FindClass(_JNIEnv*, char const*) using a bad char seperator in the 2nd arg. If you look at line 46- 48 of the pastebin link it does not look like the native function is ever invoked. The framework just throws the bad package name Findclass error. Note the first line of the native function is a log statement that is not reached at runtime.

Java layer...

public FLACStreamEncoder(String outfile, int sample_rate, int channels,

int bits_per_sample)

{

init(outfile, sample_rate, channels, bits_per_sample);

}

...

native private void init(String outfile, int sample_rate, int channels,

int bits_per_sample);

...

static {

System.loadLibrary("audioboo-native");

}

CPP layer ... the function never gets to first line log stmt.

extern "C" {

void

Java_fm_audioboo_jni_FLACStreamEncoder_init(JNIEnv * env, jobject obj,

jstring outfile, jint sample_rate, jint channels, jint bits_per_sample)

{

aj::log(ANDROID_LOG_DEBUG, LTAG, "Begin INIT extern call");

assert(sizeof(jlong) >= sizeof(FLACStreamEncoder *));

FLACStreamEncoder * encoder = new FLACStreamEncoder(

aj::convert_jstring_path(env, outfile), sample_rate, channels,

bits_per_sample);

char const * const error = encoder->init();

if (NULL != error) {

delete encoder;

aj::throwByName(env, IllegalArgumentException_classname, error);

return;

}

set_encoder(env, obj, encoder);

}

Everything worked (jni build/ android buid / android-java calls to cpp) up until android 5 build using ndk 10-C

what's new with android5/ART appears to be 'check_jni.cc' and some kind of strict mode giving ERROR:

D/FLACRecorder(26743): Setting up encoder /data/data/com.borneo.speech/files/20141123081747.flac rate: 22050 channels: 1 format 16

F/art (26743): art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: illegal class name 'fm.audioboo.jni.FLACStreamEncoder'

F/art (26743): art/runtime/check_jni.cc:65] (should be of the form 'package/Class', [Lpackage/Class;' or '[[B')

F/art (26743): art/runtime/check_jni.cc:65] in call to FindClass

F/art (26743): art/runtime/check_jni.cc:65] from void fm.audioboo.jni.FLACStreamEncoder.init(java.lang.String, int, int, int)

F

full stacktrace: note lines 46 - 48

Looking at the log, its as if the framework is doing its OWN call on 'findClass' using the 2nd, 'thisClazz' arg in the CPP:

Java_fm_audioboo_jni_FLACStreamEncoder_init(JNIEnv * env, jobject obj, ...

and its a bad arg value violating art runtime check.

But i did not run 'javah' to create any headers from the java interface because it all had been done before i got the git project.

Im stumped. The native seems to get to the function , never getting to the first line in the function ( log statemt ) , failing immediately on the

/system/lib/libart.so (art::CheckJNI::FindClass(_JNIEnv*, char const*)+66

The ndk (R10C) linked the cpp class as follows:

make: Entering directory `/home/rob/tmp/audioboo-android/app/src/main/jni'

[armeabi-v7a] Compile thumb : audioboo-ogg <= bitwise.c

[armeabi-v7a] Compile thumb : audioboo-ogg <= framing.c

[armeabi-v7a] StaticLibrary : libaudioboo-ogg.a

[armeabi-v7a] Compile thumb : audioboo-flac <= bitmath.c

[armeabi-v7a] Compile thumb : audioboo-flac <= bitreader.c

[armeabi-v7a] Compile thumb : audioboo-flac <= cpu.c

[armeabi-v7a] Compile thumb : audioboo-flac <= crc.c

[armeabi-v7a] Compile thumb : audioboo-flac <= fixed.c

[armeabi-v7a] Compile thumb : audioboo-flac <= float.c

[armeabi-v7a] Compile thumb : audioboo-flac <= format.c

[armeabi-v7a] Compile thumb : audioboo-flac <= lpc.c

[armeabi-v7a] Compile thumb : audioboo-flac <= md5.c

[armeabi-v7a] Compile thumb : audioboo-flac <= memory.c

[armeabi-v7a] Compile thumb : audioboo-flac <= metadata_iterators.c

[armeabi-v7a] Compile thumb : audioboo-flac <= metadata_object.c

[armeabi-v7a] Compile thumb : audioboo-flac <= ogg_decoder_aspect.c

[armeabi-v7a] Compile thumb : audioboo-flac <= ogg_encoder_aspect.c

[armeabi-v7a] Compile thumb : audioboo-flac <= ogg_helper.c

[armeabi-v7a] Compile thumb : audioboo-flac <= ogg_mapping.c

[armeabi-v7a] Compile thumb : audioboo-flac <= stream_decoder.c

[armeabi-v7a] Compile thumb : audioboo-flac <= stream_encoder.c

[armeabi-v7a] Compile thumb : audioboo-flac <= stream_encoder_framing.c

[armeabi-v7a] Compile thumb : audioboo-flac <= window.c

[armeabi-v7a] Compile thumb : audioboo-flac <= bitwriter.c

[armeabi-v7a] StaticLibrary : libaudioboo-flac.a

[armeabi-v7a] Compile++ thumb: audioboo-native <= FLACStreamEncoder.cpp

[armeabi-v7a] Compile++ thumb: audioboo-native <= FLACStreamDecoder.cpp

[armeabi-v7a] Compile++ thumb: audioboo-native <= util.cpp

[armeabi-v7a] StaticLibrary : libstdc++.a

[armeabi-v7a] SharedLibrary : libaudioboo-native.so

[armeabi-v7a] Install : libaudioboo-native.so => libs/armeabi-v7a/libaudioboo-native.so

make: Leaving directory `/home/rob/tmp/audioboo-android/app/src/main/jni'

Android loads the library audioboo-native above NP then throws the

JNI DETECTED ERROR IN APPLICATION: illegal class name 'fm.audioboo.jni.FLACStreamEncoder''

on the call from Java to the native function and i have no idea why?

回答1:

I've had the same problem on upgrading to Android 5, and have just sorted it.

The bug is in your native code, not in your java code. Somewhere in your native code you have a function that gets passed a FlacStreamEncoder object through jni as a jobject and you retrieve it with a line like:

jclass streamEncoder = env->FindClass("fm.audioboo.jni.FLACStreamEncoder");

But JNI is supposed to use "/" as a separator not ".", so this line should read:

jclass streamEncoder = env->FindClass("fm/audioboo/jni/FLACStreamEncoder");

instead. Previous versions of android silently ignored this problem, but now it just blows up in your face instead.

From https://android.googlesource.com/platform/art/+/kitkat-dev/runtime/check_jni.cc

// Checks that 'class_name' is a valid "fully-qualified" JNI class name, like "java/lang/Thread"

// or "[Ljava/lang/Object;". A ClassLoader can actually normalize class names a couple of

// times, so using "java.lang.Thread" instead of "java/lang/Thread" might work in some

// circumstances, but this is incorrect

void CheckClassName(const char* class_name) {

if (!IsValidJniClassName(class_name)) {

JniAbortF(function_name_,

"illegal class name '%s'\n"

" (should be of the form 'package/Class', [Lpackage/Class;' or '[[B')",

class_name);

}

}

}

来源:https://stackoverflow.com/questions/27092044/android-art-runtime-check-jni-cc-error-on-package-name

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值