Top


定義場所(file name)

jdk/src/share/classes/java/lang/ClassLoader.java

名前(function name)

    private static boolean loadLibrary0(Class fromClass, final File file) {

本体部(body)

  {- -------------------------------------------
  (1) もし指定されたファイルがなければ (あるいはアクセス権がなければ), ここでリターンする.
      ---------------------------------------- -}

            boolean exists = AccessController.doPrivileged(
                new PrivilegedAction<Object>() {
                    public Object run() {
                        return file.exists() ? Boolean.TRUE : null;
                    }})
                != null;
            if (!exists) {
                return false;
            }

  {- -------------------------------------------
  (1) ファイル名を正規化しておく.
      ---------------------------------------- -}

            String name;
            try {
                name = file.getCanonicalPath();
            } catch (IOException e) {
                return false;
            }

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

            ClassLoader loader =
                (fromClass == null) ? null : fromClass.getClassLoader();
            Vector<NativeLibrary> libs =
                loader != null ? loader.nativeLibraries : systemNativeLibraries;

  {- -------------------------------------------
  (1) もし既に自分がロード済みのライブラリであれば, ここでリターン.
      ---------------------------------------- -}

            synchronized (libs) {
                int size = libs.size();
                for (int i = 0; i < size; i++) {
                    NativeLibrary lib = libs.elementAt(i);
                    if (name.equals(lib.name)) {
                        return true;
                    }
                }

  {- -------------------------------------------
  (1) もし他のクラスローダーによってロードされていれば, UnsatisfiedLinkError.
      ---------------------------------------- -}

                synchronized (loadedLibraryNames) {
                    if (loadedLibraryNames.contains(name)) {
                        throw new UnsatisfiedLinkError
                            ("Native Library " +
                             name +
                             " already loaded in another classloader");
                    }

  {- -------------------------------------------
  (1) nativeLibraryContext の中を調べ, 同じライブラリがロード中かどうかを確かめる.
      もし同じライブラリがロード途中であれば, これ以上することはないのでここでリターン.
      (ただし, 担当のクラスローダが同じかどうかだけは確認しておく.
       もし違っていたら同じライブラリが異なるクラスローダからロードされそうになっているということなので
       UnsatisfiedLinkError.)

      (なお, これは JNI_OnLoad() の処理中にロードが発生し, 
       同じライブラリがロードされた場合に起こりうるケース.
       Runtime.load() や Runtime.loadLibrary() は synchronized なので, 
       他のスレッドが同じライブラリをロード中, という状況はあり得ない.)
      ---------------------------------------- -}

                    /* If the library is being loaded (must be by the same thread,
                     * because Runtime.load and Runtime.loadLibrary are
                     * synchronous). The reason is can occur is that the JNI_OnLoad
                     * function can cause another loadLibrary invocation.
                     *
                     * Thus we can use a static stack to hold the list of libraries
                     * we are loading.
                     *
                     * If there is a pending load operation for the library, we
                     * immediately return success; otherwise, we raise
                     * UnsatisfiedLinkError.
                     */
                    int n = nativeLibraryContext.size();
                    for (int i = 0; i < n; i++) {
                        NativeLibrary lib = nativeLibraryContext.elementAt(i);
                        if (name.equals(lib.name)) {
                            if (loader == lib.fromClass.getClassLoader()) {
                                return true;
                            } else {
                                throw new UnsatisfiedLinkError
                                    ("Native Library " +
                                     name +
                                     " is being loaded in another classloader");
                            }
                        }
                    }

  {- -------------------------------------------
  (1) 新しい NativeLibrary オブジェクトを作り, NativeLibrary.load() でライブラリのロード処理を行う.
      (なお, ロード処理の前後で nativeLibraryContext を使って現在ロード中であることが分かるようにしている)
      ---------------------------------------- -}

                    NativeLibrary lib = new NativeLibrary(fromClass, name);
                    nativeLibraryContext.push(lib);
                    try {
                        lib.load(name);
                    } finally {
                        nativeLibraryContext.pop();
                    }

  {- -------------------------------------------
  (1) ロードが成功すれば, loadedLibraryNames と libs に結果を追加し, true をリターンする.
      ---------------------------------------- -}

                    if (lib.handle != 0) {
                        loadedLibraryNames.addElement(name);
                        libs.addElement(lib);
                        return true;
                    }

  {- -------------------------------------------
  (1) ロードが失敗していたら false をリターンする.
      ---------------------------------------- -}

                    return false;
                }
            }
        }

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