Пример #1
0
jboolean rvmLoadNativeLibrary(Env* env, const char* path, ClassLoader* classLoader) {
    DynamicLib** nativeLibs = NULL;
    if (!classLoader || classLoader->parent == NULL) {
        // This is the bootstrap classloader
        nativeLibs = &bootNativeLibs;
    } else if (classLoader->parent->parent == NULL && classLoader->object.clazz->classLoader == NULL) {
        // This is the system classloader
        nativeLibs = &mainNativeLibs;
    } else {
        // Unknown classloader
        rvmThrowUnsatisfiedLinkError(env, "Unknown classloader");
        return FALSE;
    }

    char* errorMsg = NULL;
    DynamicLib* lib = rvmOpenDynamicLib(env, path, &errorMsg);
    if (!lib) {
        if (!rvmExceptionOccurred(env)) {
            rvmThrowUnsatisfiedLinkError(env, errorMsg);
        }
        return FALSE;
    }

    obtainNativeLibsLock();

    if (rvmHasDynamicLib(env, lib, *nativeLibs)) {
        // The lib is already in nativeLibs
        rvmCloseDynamicLib(env, lib);
        releaseNativeLibsLock();
        return TRUE;
    }

    jint (*JNI_OnLoad)(JavaVM*, void*) = rvmFindDynamicLibSymbol(env, lib, "JNI_OnLoad", FALSE);
    if (JNI_OnLoad) {
        // TODO: Check that JNI_OnLoad returns a supported JNI version?
        JNI_OnLoad(&env->vm->javaVM, NULL);
        if (rvmExceptionOccurred(env)) {
            releaseNativeLibsLock();
            return FALSE;
        }
    }

    rvmAddDynamicLib(env, lib, nativeLibs);

    releaseNativeLibsLock();

    return TRUE;
}
Пример #2
0
void* rvmResolveNativeMethodImpl(Env* env, NativeMethod* method, const char* shortMangledName, const char* longMangledName, ClassLoader* classLoader, void** ptr) {
    void* f = method->nativeImpl;
    if (!f) {
        DynamicLib* nativeLibs = NULL;
        if (!classLoader || classLoader->parent == NULL) {
            // This is the bootstrap classloader
            nativeLibs = bootNativeLibs;
        } else if (classLoader->parent->parent == NULL && classLoader->object.clazz->classLoader == NULL) {
            // This is the system classloader
            nativeLibs = mainNativeLibs;
        } else {
            // Unknown classloader
            rvmThrowUnsatisfiedLinkError(env, "Unknown classloader");
            return NULL;
        }

        obtainNativeLibsLock();

        TRACEF("Searching for native method using short name: %s", shortMangledName);
        f = rvmFindDynamicLibSymbol(env, nativeLibs, shortMangledName, TRUE);
        if (f) {
            TRACEF("Found native method using short name: %s", shortMangledName);
        } else if (strcmp(shortMangledName, longMangledName)) {
            TRACEF("Searching for native method using long name: %s", longMangledName);
            f = rvmFindDynamicLibSymbol(env, nativeLibs, longMangledName, TRUE);
            if (f) {
                TRACEF("Found native method using long name: %s", longMangledName);
            }
        }

        method->nativeImpl = f;

        releaseNativeLibsLock();
    }

    if (!f) {
        char* className = rvmToBinaryClassName(env, method->method.clazz->name);
        if (className) {
            rvmThrowNewf(env, java_lang_UnsatisfiedLinkError, "%s.%s%s", className, method->method.name, method->method.desc);
        }
        return NULL;
    }
    // TODO: Remember ptr to allow it to be reset when the JNI RegisterNatives/UnregisterNatives functions are called
    *ptr = f;
    return f;
}
Пример #3
0
void _bcThrowUnsatisfiedLinkError(Env* env, char* msg) {
    ENTER;
    rvmThrowUnsatisfiedLinkError(env, msg);
    LEAVEV;
}