java.lang.IllegalArgumentException: Unable to find native library main using classloader: dalvik.sys
来源:互联网 发布:阿里云域名无法使用 编辑:程序博客网 时间:2024/06/07 02:25
一个三方apk在androidN上forceclose,错误信息如下,通过对比测试,在android M上运行正常。
01-0107:06:59.989 E/AndroidRuntime( 6082): FATAL EXCEPTION: main
01-01 07:06:59.989 E/AndroidRuntime(6082): Process: com.ice.cream.maker, PID: 6082
01-01 07:06:59.989 E/AndroidRuntime(6082): java.lang.RuntimeException: Unable to start activityComponentInfo{com.ice.cream.maker/com.unity3d.player.UnityPlayerNativeActivity}:java.lang.IllegalArgumentException: Unable to find native library main usingclassloader: dalvik.system.DexClassLoader[DexPathList[[zip file"/data/user/0/com.ice.cream.maker/app_vnr/classes.jar"],nativeLibraryDirectories=[/system/lib,/vendor/lib]]]
01-01 07:06:59.989 E/AndroidRuntime(6082): atandroid.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
01-01 07:06:59.989 E/AndroidRuntime(6082): atandroid.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
01-01 07:06:59.989 E/AndroidRuntime(6082): atandroid.app.ActivityThread.-wrap12(ActivityThread.java)
01-01 07:06:59.989 E/AndroidRuntime(6082): atandroid.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
01-01 07:06:59.989 E/AndroidRuntime(6082): atandroid.os.Handler.dispatchMessage(Handler.java:102)
01-01 07:06:59.989 E/AndroidRuntime(6082): atandroid.os.Looper.loop(Looper.java:154)
01-01 07:06:59.989 E/AndroidRuntime(6082): atandroid.app.ActivityThread.main(ActivityThread.java:6126)
01-01 07:06:59.989 E/AndroidRuntime(6082): atjava.lang.reflect.Method.invoke(Native Method)
01-01 07:06:59.989 E/AndroidRuntime(6082): atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
01-01 07:06:59.989 E/AndroidRuntime(6082): atcom.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
01-01 07:06:59.989 E/AndroidRuntime(6082): Caused by: java.lang.IllegalArgumentException: Unable to find nativelibrary main using classloader: dalvik.system.DexClassLoader[DexPathList[[zipfile"/data/user/0/com.ice.cream.maker/app_vnr/classes.jar"],nativeLibraryDirectories=[/system/lib,/vendor/lib]]]
01-01 07:06:59.989 E/AndroidRuntime(6082): atandroid.app.NativeActivity.onCreate(NativeActivity.java:168)
01-01 07:06:59.989 E/AndroidRuntime(6082): atcom.unity3d.player.UnityPlayerNativeActivity.onCreate(Unknown Source)
01-01 07:06:59.989 E/AndroidRuntime(6082): atandroid.app.Activity.performCreate(Activity.java:6720)
01-01 07:06:59.989 E/AndroidRuntime(6082): atandroid.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
01-01 07:06:59.989 E/AndroidRuntime(6082): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
01-01 07:06:59.989 E/AndroidRuntime(6082): ... 9 more
01-01 07:06:59.994 W/ActivityManager(2598): Force finishing activitycom.ice.cream.maker/com.unity3d.player.UnityPlayerNativeActivity
通过log会发现问题在android.app.NativeActivity.onCreate,对比N和M的代码会发现,N的代码在打开so的时候,方式发生变化。
N的代码如下,
BaseDexClassLoader classLoader =(BaseDexClassLoader) getClassLoader();
String path= classLoader.findLibrary(libname);
if (path ==null) {
thrownew IllegalArgumentException("Unable to find native library " + libname+
" using classloader: " + classLoader.toString());
}
byte[]nativeSavedState = savedInstanceState != null
?savedInstanceState.getByteArray(KEY_NATIVE_SAVED_STATE) : null;
mNativeHandle = loadNativeCode(path, funcname, Looper.myQueue(),
getAbsolutePath(getFilesDir()), getAbsolutePath(getObbDir()),
getAbsolutePath(getExternalFilesDir(null)),
Build.VERSION.SDK_INT, getAssets(), nativeSavedState,
classLoader,classLoader.getLdLibraryPath());
而M的代码如下
String path = null;
FilelibraryFile = new File(ai.applicationInfo.nativeLibraryDir,
System.mapLibraryName(libname));
if(libraryFile.exists()) {
path =libraryFile.getPath();
}
if (path ==null) {
thrownew IllegalArgumentException("Unable to find native library: " +libname);
}
byte[]nativeSavedState = savedInstanceState != null
?savedInstanceState.getByteArray(KEY_NATIVE_SAVED_STATE) : null;
mNativeHandle = loadNativeCode(path, funcname, Looper.myQueue(),
getAbsolutePath(getFilesDir()), getAbsolutePath(getObbDir()),
getAbsolutePath(getExternalFilesDir(null)),
Build.VERSION.SDK_INT, getAssets(), nativeSavedState);
可以看出,N使用了classLoader.findLibrary,并在loadNativeCode这个native接口添加了两个参数,类加载器和so库路径。
首先,在classLoader.findLibrary的时候,就没有找到对应的so,通过对DexClassLoader的分析和调试(DexClassLoader和类加载器知识见其他文档),我们可以看到应用的类加载器在创建时,传入构造函数的参数,
12-18 03:36:57.949E/System ( 5359): shah:DexPathList:dexPath=/data/app/com.ice.cream.maker-1/base.apk
12-18 03:36:57.949 E/System ( 5359): shah:DexPathList:librarySearchPath=/data/app/com.ice.cream.maker-1/lib/arm:/system/fake-libs:/data/app/com.ice.cream.maker-1/base.apk!/lib/armeabi-v7a
12-18 03:36:57.955 E/System ( 5359): shah:DexPathList:nativeLibraryDirectories=[/data/app/com.ice.cream.maker-1/lib/arm,/system/fake-libs, /data/app/com.ice.cream.maker-1/base.apk!/lib/armeabi-v7a]
12-18 03:36:57.956 E/System ( 5359): shah:DexPathList: systemNativeLibraryDirectories=[/system/lib,/vendor/lib]
12-18 03:36:57.957 E/System ( 5359):shah:DexPathList:nativeLibraryPathElements element=directory "/data/app/com.ice.cream.maker-1/lib/arm"
12-18 03:36:57.957 E/System ( 5359): shah:DexPathList:nativeLibraryPathElements element=directory"/system/fake-libs"
12-18 03:36:57.957 E/System ( 5359):shah:DexPathList:nativeLibraryPathElements element=zip file "/data/app/com.ice.cream.maker-1/base.apk",dir "lib/armeabi-v7a"
12-18 03:36:57.958 E/System ( 5359):shah:DexPathList:nativeLibraryPathElements element=directory "/system/lib"
12-18 03:36:57.958 E/System ( 5359):shah:DexPathList:nativeLibraryPathElements element=directory "/vendor/lib"
12-18 03:36:58.015 E/System ( 5359): shah:DexPathList: dexPath=/data/user/0/com.ice.cream.maker/app_vnr/classes.jar
12-18 03:36:58.015 E/System ( 5359): shah:DexPathList: librarySearchPath=null
12-18 03:36:58.015 E/System ( 5359): shah:DexPathList:optimizedDirectory=/data/user/0/com.ice.cream.maker/app_vnr
可以看到,在用DexClassLoader加载的优化后的classes.jar文件对应的librarySearchPath为null,那么在classLoader.findLibrary的时候,自然是找不到对应的so库了,估计这个三方应用在使用DexClassLoader的时候,并没有设置对相应的librarySearchPath值。
因为loadNativeCode也发生了变化,这里顺便看看android N对loadNativeCode的修改,这是一个native函数,映射在android_app_NativeActivity.cpp(frameworks\base\core\jni),对应的函数是loadNativeCode_native,函数有一点长,N和M的主要差别在打开库文件的方式:
M
void* handle = dlopen(pathStr, RTLD_LAZY);
N
void* handle = OpenNativeLibrary(env,sdkVersion, pathStr, classLoader, libraryPath);
再一路看下去,
Native_loader.cpp(system\core\libnativeloader),根据宏开关和参数可以看出通用的调用流程,在N上增加了命名空间的处理,并且这个目录和文件是N上新增的,专门用来处理命名空间的。
void*OpenNativeLibrary(JNIEnv* env,
int32_t target_sdk_version,
const char* path,
jobject class_loader,
jstring library_path) {
#if defined(__ANDROID__)
UNUSED(target_sdk_version);
if (class_loader== nullptr) {
returndlopen(path, RTLD_NOW);
}
std::lock_guard<std::mutex> guard(g_namespaces_mutex);
android_namespace_t* ns =g_namespaces->FindNamespaceByClassLoader(env, class_loader);
if (ns ==nullptr) {
// This is thecase where the classloader was not created by ApplicationLoaders
// In this case we create an isolatednot-shared namespace for it.
ns =g_namespaces->Create(env, class_loader, false, library_path, nullptr);
if (ns ==nullptr) {
returnnullptr;
}
}
android_dlextinfoextinfo;
extinfo.flags =ANDROID_DLEXT_USE_NAMESPACE;
extinfo.library_namespace = ns;
returnandroid_dlopen_ext(path, RTLD_NOW, &extinfo);
#else
UNUSED(env,target_sdk_version, class_loader, library_path);
returndlopen(path, RTLD_NOW);
#endif
}
Dlfcn.cpp(bionic\linker):void* android_dlopen_ext()
void*android_dlopen_ext(const char* filename, int flags, const android_dlextinfo*extinfo) {
void* caller_addr= __builtin_return_address(0);
returndlopen_ext(filename, flags, extinfo, caller_addr);
}
最后 通过dlopen_ext调用do_dlopen,打开库文件,这个处理逻辑和dlopen是一样的,所以实际只增加了命名空间的处理。
static void*dlopen_ext(const char* filename, int flags,
const android_dlextinfo* extinfo, void* caller_addr) {
ScopedPthreadMutexLocker locker(&g_dl_mutex);
void* result =do_dlopen(filename, flags, extinfo, caller_addr);
if (result ==nullptr) {
__bionic_format_dlerror("dlopen failed",linker_get_error_buffer());
return nullptr;
}
return result;
}
void* dlopen(constchar* filename, int flags) {
void* caller_addr= __builtin_return_address(0);
returndlopen_ext(filename, flags, nullptr, caller_addr);
}
- java.lang.IllegalArgumentException: Unable to find native library main using classloader: dalvik.sys
- Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library
- NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java class
- Unable to load native-hadoop library for your platform... using builtin-java classes where applicabl
- Unable to load native-hadoop library for your platform... using builtin-java classes where applicab
- Unable to load native-hadoop library for your platform... using builtin-java classes where applicab
- unable to load native-hadoop library for your platform using builtin-java classes
- Unable to load native-hadoop library for your platform... using builtin-java classes where applicabl
- hadoop:Unable to load native-hadoop library for your platform... using builtin-java classes where ap
- hadoop Unable to load native-hadoop library for your platform... using builtin-java classes where a
- Unable to load native-hadoop library for your platform... using builtin-java classes where applicabl
- Unable to load native-hadoop library for your platform... using builtin-java classes where applicabl
- java.lang.UnsatisfiedLinkError: Native Library * already loaded in another classloader
- Native.loadLibrary Caused by: java.lang.UnsatisfiedLinkError: Unable to load library
- java.lang.UnsatisfiedLinkError: Unable to load library
- Caused by: java.lang.IllegalStateException: Unable to find a single main class from问题解决
- Unable to load sqlite_jni: java.lang.UnsatisfiedLinkError: Native Library D:/resin/bin/sqlite_jni.dll already loaded in another
- 找不到so文件java.lang.UnsatisfiedLinkError: dalvik.sys.... couldn't find "libijkffmpeg.so"
- Android:ExpandableTextView 的扩展
- WebService简单介绍
- cookie 和session 的区别详解
- windows NT到底是什么
- 使用VLC播放组播地址
- java.lang.IllegalArgumentException: Unable to find native library main using classloader: dalvik.sys
- NIO读写文件
- 通配符
- 奇怪的函数 题解
- 变量的解构赋值
- linux硬链接与软链接
- static和volatile的用法
- 优雅地实现入参非空判断
- JavaScript中的基本类型和引用类型的复制使用