Top


定義場所(file name)

jdk/src/share/native/java/lang/ClassLoader.c

説明(description)

/*
 * Class:     java_lang_ClassLoader_NativeLibrary
 * Method:    load
 * Signature: (Ljava/lang/String;)J
 */

名前(function name)

JNIEXPORT void JNICALL
Java_java_lang_ClassLoader_00024NativeLibrary_load
  (JNIEnv *env, jobject this, jstring name)
{

本体部(body)

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

        const char *cname;
        jint jniVersion;
        jthrowable cause;
        void * handle;

  {- -------------------------------------------
  (1) (まだ初期化が終わっていなければ) 初期化を行っておく.
      初期化中にエラーが起きた場合は, ここでリターン.
      ---------------------------------------- -}

        if (!initIDs(env))
            return;

  {- -------------------------------------------
  (1) JNU_GetStringPlatformChars() で
      ライブラリ名を実行環境の文字エンコーディングに合わせた文字列に変換しておく.
      変換処理が失敗したら, ここでリターン.
      ---------------------------------------- -}

        cname = JNU_GetStringPlatformChars(env, name, 0);
        if (cname == 0)
            return;

  {- -------------------------------------------
  (1) JVM_LoadLibrary() でライブラリをロードする.
      ---------------------------------------- -}

        handle = JVM_LoadLibrary(cname);

  {- -------------------------------------------
  (1) (以下の処理は, JVM_LoadLibrary() によるロードの成否に応じて 2通りに分岐)
      ---------------------------------------- -}

  {- -------------------------------------------
  (1) もし JVM_LoadLibrary() でのロードが成功していれば, 以下の処理を行う.
      ---------------------------------------- -}

        if (handle) {

    {- -------------------------------------------
  (1.1) JVM_FindLibraryEntry() を呼んで, JNI_OnLoad シンボルが含まれているかどうかを調べる.
        (JNI_OnLoad を示すシンボルはプラットフォームによっては候補が複数あることがあるため, ループで処理.
         候補のどれかが見つかれば終了.)
        ---------------------------------------- -}

            const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS;
            JNI_OnLoad_t JNI_OnLoad;
            unsigned int i;
            for (i = 0; i < sizeof(onLoadSymbols) / sizeof(char *); i++) {
                JNI_OnLoad = (JNI_OnLoad_t)
                    JVM_FindLibraryEntry(handle, onLoadSymbols[i]);
                if (JNI_OnLoad) {
                    break;
                }
            }

    {- -------------------------------------------
  (1.1) もし JNI_OnLoad シンボルが見つかれば, それを呼び出し, 返値から jni version を取得する.
        JNI_OnLoad シンボルが見つからなかった場合は, jni version は 1.1 とする.
        ---------------------------------------- -}

            if (JNI_OnLoad) {
                JavaVM *jvm;
                (*env)->GetJavaVM(env, &jvm);
                jniVersion = (*JNI_OnLoad)(jvm, NULL);
            } else {
                jniVersion = 0x00010001;
            }

    {- -------------------------------------------
  (1.1) もし例外が発生していたら, JVM_UnloadLibrary() でライブラリをアンロードする.
        (発生した例外はそのまま rethrow)
        ---------------------------------------- -}

            cause = (*env)->ExceptionOccurred(env);
            if (cause) {
                (*env)->ExceptionClear(env);
                (*env)->Throw(env, cause);
                JVM_UnloadLibrary(handle);
                goto done;
            }

    {- -------------------------------------------
  (1.1) もしロードしたライブラリの jni version がサポート対象外であれば, 
        UnsatisfiedLinkError を送出し, ロードしたライブラリも JVM_UnloadLibrary() でアンロードする.
        ---------------------------------------- -}

            if (!JVM_IsSupportedJNIVersion(jniVersion)) {
                char msg[256];
                jio_snprintf(msg, sizeof(msg),
                             "unsupported JNI version 0x%08X required by %s",
                             jniVersion, cname);
                JNU_ThrowByName(env, "java/lang/UnsatisfiedLinkError", msg);
                JVM_UnloadLibrary(handle);
                goto done;
            }

    {- -------------------------------------------
  (1.1) 取得した jniVersion 情報を, NativeLibrary の jniVersion フィールドにセットする.
        ---------------------------------------- -}

            (*env)->SetIntField(env, this, jniVersionID, jniVersion);

  {- -------------------------------------------
  (1) もし JVM_LoadLibrary() でのロードが失敗していれば, 
      NativeLibrary の handle フィールドを 0 にセットした後, 同じ例外を rethrow する.
      ---------------------------------------- -}

        } else {
            cause = (*env)->ExceptionOccurred(env);
            if (cause) {
                (*env)->ExceptionClear(env);
                (*env)->SetLongField(env, this, handleID, (jlong)0);
                (*env)->Throw(env, cause);
            }
            goto done;
        }

  {- -------------------------------------------
  (1) NativeLibrary の handle フィールドにロード結果のポインタを格納する.
      ---------------------------------------- -}

        (*env)->SetLongField(env, this, handleID, ptr_to_jlong(handle));

  {- -------------------------------------------
  (1) (後始末)
      ---------------------------------------- -}

     done:
        JNU_ReleaseStringPlatformChars(env, name, cname);
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.