1725 * into the system are entered into the <tt>systemNativeLibraries</tt>
1726 * vector.
1727 *
1728 * <p> Every native library requires a particular version of JNI. This is
1729 * denoted by the private <tt>jniVersion</tt> field. This field is set by
1730 * the VM when it loads the library, and used by the VM to pass the correct
1731 * version of JNI to the native methods. </p>
1732 *
1733 * @see ClassLoader
1734 * @since 1.2
1735 */
1736 static class NativeLibrary {
1737 // opaque handle to native library, used in native code.
1738 long handle;
1739 // the version of JNI environment the native library requires.
1740 private int jniVersion;
1741 // the class from which the library is loaded, also indicates
1742 // the loader this native library belongs.
1743 private Class<?> fromClass;
1744 // the canonicalized name of the native library.
1745 String name;
1746
1747 native void load(String name);
1748 native long find(String name);
1749 native void unload();
1750
1751 public NativeLibrary(Class<?> fromClass, String name) {
1752 this.name = name;
1753 this.fromClass = fromClass;
1754 }
1755
1756 protected void finalize() {
1757 synchronized (loadedLibraryNames) {
1758 if (fromClass.getClassLoader() != null && handle != 0) {
1759 /* remove the native library name */
1760 int size = loadedLibraryNames.size();
1761 for (int i = 0; i < size; i++) {
1762 if (name.equals(loadedLibraryNames.elementAt(i))) {
1763 loadedLibraryNames.removeElementAt(i);
1764 break;
1765 }
1766 }
1767 /* unload the library. */
1768 ClassLoader.nativeLibraryContext.push(this);
1769 try {
1770 unload();
1771 } finally {
1772 ClassLoader.nativeLibraryContext.pop();
1773 }
1774 }
1775 }
1776 }
1777 // Invoked in the VM to determine the context class in
1778 // JNI_Load/JNI_Unload
1779 static Class<?> getFromClass() {
1780 return ClassLoader.nativeLibraryContext.peek().fromClass;
1781 }
1782 }
1783
1784 // All native library names we've loaded.
1785 private static Vector<String> loadedLibraryNames = new Vector<>();
1786
1787 // Native libraries belonging to system classes.
1788 private static Vector<NativeLibrary> systemNativeLibraries
1789 = new Vector<>();
1790
1870 }
1871 }
1872 if (loader != null) {
1873 for (int i = 0 ; i < usr_paths.length ; i++) {
1874 File libfile = new File(usr_paths[i],
1875 System.mapLibraryName(name));
1876 if (loadLibrary0(fromClass, libfile)) {
1877 return;
1878 }
1879 libfile = ClassLoaderHelper.mapAlternativeName(libfile);
1880 if (libfile != null && loadLibrary0(fromClass, libfile)) {
1881 return;
1882 }
1883 }
1884 }
1885 // Oops, it failed
1886 throw new UnsatisfiedLinkError("no " + name + " in java.library.path");
1887 }
1888
1889 private static boolean loadLibrary0(Class<?> fromClass, final File file) {
1890 boolean exists = AccessController.doPrivileged(
1891 new PrivilegedAction<Object>() {
1892 public Object run() {
1893 return file.exists() ? Boolean.TRUE : null;
1894 }})
1895 != null;
1896 if (!exists) {
1897 return false;
1898 }
1899 String name;
1900 try {
1901 name = file.getCanonicalPath();
1902 } catch (IOException e) {
1903 return false;
1904 }
1905 ClassLoader loader =
1906 (fromClass == null) ? null : fromClass.getClassLoader();
1907 Vector<NativeLibrary> libs =
1908 loader != null ? loader.nativeLibraries : systemNativeLibraries;
1909 synchronized (libs) {
1910 int size = libs.size();
1911 for (int i = 0; i < size; i++) {
1912 NativeLibrary lib = libs.elementAt(i);
1913 if (name.equals(lib.name)) {
1914 return true;
1915 }
1916 }
1917
1918 synchronized (loadedLibraryNames) {
1919 if (loadedLibraryNames.contains(name)) {
1920 throw new UnsatisfiedLinkError
1921 ("Native Library " +
1922 name +
1923 " already loaded in another classloader");
1924 }
1931 * we are loading.
1932 *
1933 * If there is a pending load operation for the library, we
1934 * immediately return success; otherwise, we raise
1935 * UnsatisfiedLinkError.
1936 */
1937 int n = nativeLibraryContext.size();
1938 for (int i = 0; i < n; i++) {
1939 NativeLibrary lib = nativeLibraryContext.elementAt(i);
1940 if (name.equals(lib.name)) {
1941 if (loader == lib.fromClass.getClassLoader()) {
1942 return true;
1943 } else {
1944 throw new UnsatisfiedLinkError
1945 ("Native Library " +
1946 name +
1947 " is being loaded in another classloader");
1948 }
1949 }
1950 }
1951 NativeLibrary lib = new NativeLibrary(fromClass, name);
1952 nativeLibraryContext.push(lib);
1953 try {
1954 lib.load(name);
1955 } finally {
1956 nativeLibraryContext.pop();
1957 }
1958 if (lib.handle != 0) {
1959 loadedLibraryNames.addElement(name);
1960 libs.addElement(lib);
1961 return true;
1962 }
1963 return false;
1964 }
1965 }
1966 }
1967
1968 // Invoked in the VM class linking code.
1969 static long findNative(ClassLoader loader, String name) {
1970 Vector<NativeLibrary> libs =
1971 loader != null ? loader.nativeLibraries : systemNativeLibraries;
1972 synchronized (libs) {
1973 int size = libs.size();
1974 for (int i = 0; i < size; i++) {
1975 NativeLibrary lib = libs.elementAt(i);
1976 long entry = lib.find(name);
1977 if (entry != 0)
1978 return entry;
|
1725 * into the system are entered into the <tt>systemNativeLibraries</tt>
1726 * vector.
1727 *
1728 * <p> Every native library requires a particular version of JNI. This is
1729 * denoted by the private <tt>jniVersion</tt> field. This field is set by
1730 * the VM when it loads the library, and used by the VM to pass the correct
1731 * version of JNI to the native methods. </p>
1732 *
1733 * @see ClassLoader
1734 * @since 1.2
1735 */
1736 static class NativeLibrary {
1737 // opaque handle to native library, used in native code.
1738 long handle;
1739 // the version of JNI environment the native library requires.
1740 private int jniVersion;
1741 // the class from which the library is loaded, also indicates
1742 // the loader this native library belongs.
1743 private Class<?> fromClass;
1744 // the canonicalized name of the native library.
1745 // or static library name
1746 String name;
1747 // Indicates if the native library is linked into the VM
1748 boolean isBuiltin;
1749 // Indicates if the native library is loaded
1750 boolean loaded;
1751 native void load(String name, boolean isBuiltin);
1752
1753 native long find(String name);
1754 native void unload(String name, boolean isBuiltin);
1755 static native String findBuiltinLib(String name);
1756
1757 public NativeLibrary(Class<?> fromClass, String name, boolean isBuiltin) {
1758 this.name = name;
1759 this.fromClass = fromClass;
1760 this.isBuiltin = isBuiltin;
1761 }
1762
1763 protected void finalize() {
1764 synchronized (loadedLibraryNames) {
1765 if (fromClass.getClassLoader() != null && loaded) {
1766 /* remove the native library name */
1767 int size = loadedLibraryNames.size();
1768 for (int i = 0; i < size; i++) {
1769 if (name.equals(loadedLibraryNames.elementAt(i))) {
1770 loadedLibraryNames.removeElementAt(i);
1771 break;
1772 }
1773 }
1774 /* unload the library. */
1775 ClassLoader.nativeLibraryContext.push(this);
1776 try {
1777 unload(name, isBuiltin);
1778 } finally {
1779 ClassLoader.nativeLibraryContext.pop();
1780 }
1781 }
1782 }
1783 }
1784 // Invoked in the VM to determine the context class in
1785 // JNI_Load/JNI_Unload
1786 static Class<?> getFromClass() {
1787 return ClassLoader.nativeLibraryContext.peek().fromClass;
1788 }
1789 }
1790
1791 // All native library names we've loaded.
1792 private static Vector<String> loadedLibraryNames = new Vector<>();
1793
1794 // Native libraries belonging to system classes.
1795 private static Vector<NativeLibrary> systemNativeLibraries
1796 = new Vector<>();
1797
1877 }
1878 }
1879 if (loader != null) {
1880 for (int i = 0 ; i < usr_paths.length ; i++) {
1881 File libfile = new File(usr_paths[i],
1882 System.mapLibraryName(name));
1883 if (loadLibrary0(fromClass, libfile)) {
1884 return;
1885 }
1886 libfile = ClassLoaderHelper.mapAlternativeName(libfile);
1887 if (libfile != null && loadLibrary0(fromClass, libfile)) {
1888 return;
1889 }
1890 }
1891 }
1892 // Oops, it failed
1893 throw new UnsatisfiedLinkError("no " + name + " in java.library.path");
1894 }
1895
1896 private static boolean loadLibrary0(Class<?> fromClass, final File file) {
1897 // Check to see if we're attempting to access a static library
1898 // System.out.println("loadLibrary0: filename: " + file.getName());
1899 String name = NativeLibrary.findBuiltinLib(file.getName());
1900 // System.out.println("loadLibrary0: name: " + name);
1901 boolean isBuiltin = (name != null);
1902 if (!isBuiltin) {
1903 boolean exists = AccessController.doPrivileged(
1904 new PrivilegedAction<Object>() {
1905 public Object run() {
1906 return file.exists() ? Boolean.TRUE : null;
1907 }})
1908 != null;
1909 if (!exists) {
1910 return false;
1911 }
1912 try {
1913 name = file.getCanonicalPath();
1914 } catch (IOException e) {
1915 return false;
1916 }
1917 }
1918 ClassLoader loader =
1919 (fromClass == null) ? null : fromClass.getClassLoader();
1920 Vector<NativeLibrary> libs =
1921 loader != null ? loader.nativeLibraries : systemNativeLibraries;
1922 synchronized (libs) {
1923 int size = libs.size();
1924 for (int i = 0; i < size; i++) {
1925 NativeLibrary lib = libs.elementAt(i);
1926 if (name.equals(lib.name)) {
1927 return true;
1928 }
1929 }
1930
1931 synchronized (loadedLibraryNames) {
1932 if (loadedLibraryNames.contains(name)) {
1933 throw new UnsatisfiedLinkError
1934 ("Native Library " +
1935 name +
1936 " already loaded in another classloader");
1937 }
1944 * we are loading.
1945 *
1946 * If there is a pending load operation for the library, we
1947 * immediately return success; otherwise, we raise
1948 * UnsatisfiedLinkError.
1949 */
1950 int n = nativeLibraryContext.size();
1951 for (int i = 0; i < n; i++) {
1952 NativeLibrary lib = nativeLibraryContext.elementAt(i);
1953 if (name.equals(lib.name)) {
1954 if (loader == lib.fromClass.getClassLoader()) {
1955 return true;
1956 } else {
1957 throw new UnsatisfiedLinkError
1958 ("Native Library " +
1959 name +
1960 " is being loaded in another classloader");
1961 }
1962 }
1963 }
1964 NativeLibrary lib = new NativeLibrary(fromClass, name, isBuiltin);
1965 nativeLibraryContext.push(lib);
1966 try {
1967 lib.load(name, isBuiltin);
1968 } finally {
1969 nativeLibraryContext.pop();
1970 }
1971 if (lib.loaded) {
1972 loadedLibraryNames.addElement(name);
1973 libs.addElement(lib);
1974 return true;
1975 }
1976 return false;
1977 }
1978 }
1979 }
1980
1981 // Invoked in the VM class linking code.
1982 static long findNative(ClassLoader loader, String name) {
1983 Vector<NativeLibrary> libs =
1984 loader != null ? loader.nativeLibraries : systemNativeLibraries;
1985 synchronized (libs) {
1986 int size = libs.size();
1987 for (int i = 0; i < size; i++) {
1988 NativeLibrary lib = libs.elementAt(i);
1989 long entry = lib.find(name);
1990 if (entry != 0)
1991 return entry;
|