Покопался немного в коде, интересуют комменты от разработчиков JVM. Надо может быть отдельный пост написать про это.
Итак, все знают что загружаются нативные библиотеки через класс java.lang.ClassLoader, и и точка перехода в нативный код — java.lang.ClassLoader.NativeLibrary.load.
Смотрим jdk/j2se/src/share/native/java/lang/ClassLoader.c, видим:
....
JNIEXPORT void JNICALL
Java_java_lang_ClassLoader_00024NativeLibrary_load
(JNIEnv *env, jobject this, jstring name)
{
const char *cname;
jint jniVersion;
jthrowable cause;
void * handle;
if (!initIDs(env))
return;
cname = JNU_GetStringPlatformChars(env, name, 0);
if (cname == 0)
return;
handle = JVM_LoadLibrary(cname);
if (handle) {
// разнообразные проверки и обрабока исключений
}
...
Смотрим где определена функция JVM_LoadLibrary, пролистав хедеры jvm.h, находим что-то похожее на то, что нам нужно в файле jdk/hotspot/src/share/vm/prims/jvm.cpp:
JVM_ENTRY_NO_ENV(void*, JVM_LoadLibrary(const char* name))
//%note jvm_ct
JVMWrapper2("JVM_LoadLibrary (%s)", name);
char ebuf[1024];
void *load_result;
{
ThreadToNativeFromVM ttnfvm(thread);
load_result = hpi::dll_load(name, ebuf, sizeof ebuf);
}
if (load_result == NULL) {
char msg[1024];
jio_snprintf(msg, sizeof msg, "%s: %s", name, ebuf);
...
Handle h_exception =
Exceptions::new_exception(thread,
vmSymbols::java_lang_UnsatisfiedLinkError(),
msg, Exceptions::unsafe_to_utf8);
THROW_HANDLE_0(h_exception);
}
Т.е. функция dll_load уже похожа на ту, где должен идти натуральный вызов системных функций для загрузки (POSIX/WINAPI), иначе это уже слишком много уровней получается. Смотрим файл jdk/hotspot/src/os/os/linux/vm/os_linux.cpp: видим:
// Loads .dll/.so and
// in case of error it checks if .dll/.so was built for the
// same architecture as Hotspot is running on
void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
{
void * result= ::dlopen(filename, RTLD_LAZY);
if (result != NULL) {
// Successful loading
return result;
}
Ха! Т.е. shared object-ы таки загружаются без добавочного флага RTLD_NOLOAD! Т.е. JVM не проверяет, перед загрузкой, загружена соотв. либа или еще нет?
Для сравнения посмотрим аналогичный код Windows, смотрим файл os_windows.cpp:
// Loads .dll/.so and
// in case of error it checks if .dll/.so was built for the
// same architecture as Hotspot is running on
void * os::dll_load(const char *name, char *ebuf, int ebuflen)
{
void * result = LoadLibrary(name);
if (result != NULL)
{
return result;
}
А теперь смотрим на документация в LoadLibrary здесь:
msdn.microsoft.com/en-us/library/windows/desktop/ms682586.aspx
If a DLL with the same module name is already loaded in memory, the system checks only for redirection and a manifest before resolving to the loaded DLL, no matter which directory it is in. The system does not search for the DLL.
Т.е. поведение для линукса и виндовса будет различное в данном случае.
Читаем: