Use shared namespaces for bundled apps
Shared namespaces clone the list of loaded native
libraries from the caller namespace. This allows
classloaders for bundled apps to share already loaded
libraries with default namespace.
Bug: http://b/26165097
Bug: http://b/22548808
Change-Id: Ia90b603a0ca97194618b82fb191d6790a4b1f281
(cherry picked from commit 986f650d8b552e8b7dbebef1f50f015e7850edfc)
diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc
index 5ab55e0..8d60be2 100644
--- a/compiler/jni/jni_compiler_test.cc
+++ b/compiler/jni/jni_compiler_test.cc
@@ -220,7 +220,8 @@
std::string reason;
ASSERT_TRUE(Runtime::Current()->GetJavaVM()->
- LoadNativeLibrary(env_, "", class_loader_, nullptr, nullptr, &reason))
+ LoadNativeLibrary(env_, "", class_loader_, /* is_shared_namespace */ false,
+ nullptr, nullptr, &reason))
<< reason;
jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 24);
@@ -235,7 +236,8 @@
std::string reason;
ASSERT_TRUE(Runtime::Current()->GetJavaVM()->
- LoadNativeLibrary(env_, "", class_loader_, nullptr, nullptr, &reason))
+ LoadNativeLibrary(env_, "", class_loader_, /* is_shared_namespace */ false,
+ nullptr, nullptr, &reason))
<< reason;
jint result = env_->CallStaticIntMethod(jklass_, jmethod_, 42);
diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc
index 15f5122..5c44193 100644
--- a/runtime/java_vm_ext.cc
+++ b/runtime/java_vm_ext.cc
@@ -717,8 +717,8 @@
}
bool JavaVMExt::LoadNativeLibrary(JNIEnv* env, const std::string& path, jobject class_loader,
- jstring library_path, jstring permitted_path,
- std::string* error_msg) {
+ bool is_shared_namespace, jstring library_path,
+ jstring permitted_path, std::string* error_msg) {
error_msg->clear();
// See if we've already loaded this library. If we have, and the class loader
@@ -777,8 +777,9 @@
Locks::mutator_lock_->AssertNotHeld(self);
const char* path_str = path.empty() ? nullptr : path.c_str();
- void* handle = android::OpenNativeLibrary(env, runtime_->GetTargetSdkVersion(),
- path_str, class_loader, library_path, permitted_path);
+ void* handle = android::OpenNativeLibrary(env, runtime_->GetTargetSdkVersion(), path_str,
+ class_loader, is_shared_namespace, library_path,
+ permitted_path);
bool needs_native_bridge = false;
if (handle == nullptr) {
if (android::NativeBridgeIsSupported(path_str)) {
diff --git a/runtime/java_vm_ext.h b/runtime/java_vm_ext.h
index 8559769..8cae1e5 100644
--- a/runtime/java_vm_ext.h
+++ b/runtime/java_vm_ext.h
@@ -85,8 +85,9 @@
* Returns 'true' on success. On failure, sets 'error_msg' to a
* human-readable description of the error.
*/
- bool LoadNativeLibrary(JNIEnv* env, const std::string& path, jobject javaLoader,
- jstring library_path, jstring permitted_path, std::string* error_msg);
+ bool LoadNativeLibrary(JNIEnv* env, const std::string& path, jobject class_loader,
+ bool is_shared_namespace, jstring library_path, jstring permitted_path,
+ std::string* error_msg);
// Unload native libraries with cleared class loaders.
void UnloadNativeLibraries()
diff --git a/runtime/native/java_lang_Runtime.cc b/runtime/native/java_lang_Runtime.cc
index 4a1e6c2..f42a17d 100644
--- a/runtime/native/java_lang_Runtime.cc
+++ b/runtime/native/java_lang_Runtime.cc
@@ -68,7 +68,8 @@
}
static jstring Runtime_nativeLoad(JNIEnv* env, jclass, jstring javaFilename, jobject javaLoader,
- jstring javaLdLibraryPath, jstring javaIsolationPath) {
+ jboolean isSharedNamespace, jstring javaLibrarySearchPath,
+ jstring javaLibraryPermittedPath) {
ScopedUtfChars filename(env, javaFilename);
if (filename.c_str() == nullptr) {
return nullptr;
@@ -80,14 +81,19 @@
// linker namespace instead of global LD_LIBRARY_PATH
// (23 is Marshmallow)
if (target_sdk_version <= INT_MAX) {
- SetLdLibraryPath(env, javaLdLibraryPath);
+ SetLdLibraryPath(env, javaLibrarySearchPath);
}
std::string error_msg;
{
JavaVMExt* vm = Runtime::Current()->GetJavaVM();
- bool success = vm->LoadNativeLibrary(env, filename.c_str(), javaLoader,
- javaLdLibraryPath, javaIsolationPath, &error_msg);
+ bool success = vm->LoadNativeLibrary(env,
+ filename.c_str(),
+ javaLoader,
+ isSharedNamespace == JNI_TRUE,
+ javaLibrarySearchPath,
+ javaLibraryPermittedPath,
+ &error_msg);
if (success) {
return nullptr;
}
@@ -115,7 +121,7 @@
NATIVE_METHOD(Runtime, gc, "()V"),
NATIVE_METHOD(Runtime, maxMemory, "!()J"),
NATIVE_METHOD(Runtime, nativeExit, "(I)V"),
- NATIVE_METHOD(Runtime, nativeLoad, "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
+ NATIVE_METHOD(Runtime, nativeLoad, "(Ljava/lang/String;Ljava/lang/ClassLoader;ZLjava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
NATIVE_METHOD(Runtime, totalMemory, "!()J"),
};
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 02747d0..fde2063 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1219,7 +1219,9 @@
// the library that implements System.loadLibrary!
{
std::string error_msg;
- if (!java_vm_->LoadNativeLibrary(env, "libjavacore.so", nullptr, nullptr, nullptr, &error_msg)) {
+ if (!java_vm_->LoadNativeLibrary(env, "libjavacore.so", nullptr,
+ /* is_shared_namespace */ false,
+ nullptr, nullptr, &error_msg)) {
LOG(FATAL) << "LoadNativeLibrary failed for \"libjavacore.so\": " << error_msg;
}
}
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 2b778d9..a47a08e 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -381,7 +381,7 @@
ScopedLocalRef<jclass> java_lang_Runtime(env, env->FindClass("java/lang/Runtime"));
java_lang_Runtime_nativeLoad =
CacheMethod(env, java_lang_Runtime.get(), true, "nativeLoad",
- "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)"
+ "(Ljava/lang/String;Ljava/lang/ClassLoader;ZLjava/lang/String;Ljava/lang/String;)"
"Ljava/lang/String;");
}