From cc76889a6fe96cffb91c9a3aa7934878c0ecd97e Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Fri, 4 May 2012 01:12:25 +0200
Subject: Use ClassLoader to find JNI native libraries. ClassLoader was only
 used for tool native libraries.

NativeLibrary: Expose 'String findLibrary(String libName, ClassLoader loader)',
               allowing utilization of System.load(loader.findLibrary(libName)).

JNILibLoaderBase.loadLibrary(): Add optional ClassLoader argument, used to locate the library

DynamicLibraryBundle: Use DynamicLibraryInfo's ClassLoader to find native libraries (tool + jni)
---
 .../com/jogamp/common/jvm/JNILibLoaderBase.java    | 78 +++++++++++++++-------
 .../com/jogamp/common/os/DynamicLibraryBundle.java | 16 ++---
 src/java/com/jogamp/common/os/NativeLibrary.java   | 17 +++--
 src/java/com/jogamp/common/os/Platform.java        |  4 +-
 .../test/junit/generation/BindingJNILibLoader.java |  4 +-
 5 files changed, 77 insertions(+), 42 deletions(-)

(limited to 'src')

diff --git a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java
index 8d6e428..94bc7e7 100644
--- a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java
+++ b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java
@@ -46,10 +46,10 @@ import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.HashSet;
 
+import com.jogamp.common.os.NativeLibrary;
 import com.jogamp.common.os.Platform;
 import com.jogamp.common.util.JarUtil;
 import com.jogamp.common.util.PropertyAccess;
-import com.jogamp.common.util.SecurityUtil;
 import com.jogamp.common.util.cache.TempJarCache;
 
 import jogamp.common.Debug;
@@ -63,9 +63,10 @@ public class JNILibLoaderBase {
      * The implementation should ignore, if the library has been loaded already.<br>
      * @param libname the library to load
      * @param ignoreError if true, errors during loading the library should be ignored 
+     * @param cl optional ClassLoader, used to locate the library
      * @return true if library loaded successful
      */
-    boolean loadLibrary(String libname, boolean ignoreError);
+    boolean loadLibrary(String libname, boolean ignoreError, ClassLoader cl);
 
     /**
      * Loads the library specified by libname.<br>
@@ -74,16 +75,17 @@ public class JNILibLoaderBase {
      * @param libname the library to load
      * @param preload the libraries to load before loading the main library if not null
      * @param preloadIgnoreError if true, errors during loading the preload-libraries should be ignored 
+     * @param cl optional ClassLoader, used to locate the library
      */
-    void loadLibrary(String libname, String[] preload, boolean preloadIgnoreError);
+    void loadLibrary(String libname, String[] preload, boolean preloadIgnoreError, ClassLoader cl);
   }
   
   private static class DefaultAction implements LoaderAction {
-    public boolean loadLibrary(String libname, boolean ignoreError) {
+    public boolean loadLibrary(String libname, boolean ignoreError, ClassLoader cl) {
       boolean res = true;
       if(!isLoaded(libname)) {
           try {
-            loadLibraryInternal(libname);
+            loadLibraryInternal(libname, cl);
             addLoaded(libname);
             if(DEBUG) {
                 System.err.println("JNILibLoaderBase: loaded "+libname);
@@ -101,14 +103,14 @@ public class JNILibLoaderBase {
       return res;
     }
 
-    public void loadLibrary(String libname, String[] preload, boolean preloadIgnoreError) {
+    public void loadLibrary(String libname, String[] preload, boolean preloadIgnoreError, ClassLoader cl) {
       if(!isLoaded(libname)) {
           if (null!=preload) {
             for (int i=0; i<preload.length; i++) {
-              loadLibrary(preload[i], preloadIgnoreError);
+              loadLibrary(preload[i], preloadIgnoreError, cl);
             }
           }
-          loadLibrary(libname, false);
+          loadLibrary(libname, false, cl);
       }
     }
   }
@@ -211,17 +213,34 @@ public class JNILibLoaderBase {
     return res;
   }
   
-  protected static synchronized boolean loadLibrary(String libname, boolean ignoreError) {
-    if (loaderAction != null) {
-        return loaderAction.loadLibrary(libname, ignoreError);    
-    }
-    return false;
+  /**
+   * Loads the library specified by libname, using the {@link LoaderAction} set by {@link #setLoadingAction(LoaderAction)}.<br>
+   * The implementation should ignore, if the library has been loaded already.<br>
+   * @param libname the library to load
+   * @param ignoreError if true, errors during loading the library should be ignored 
+   * @param cl optional ClassLoader, used to locate the library
+   * @return true if library loaded successful
+   */
+  protected static synchronized boolean loadLibrary(String libname, boolean ignoreError, ClassLoader cl) {
+      if (loaderAction != null) {
+          return loaderAction.loadLibrary(libname, ignoreError, cl);    
+      }
+      return false;
   }
   
-  protected static synchronized void loadLibrary(String libname, String[] preload, boolean preloadIgnoreError) {
-    if (loaderAction != null) {
-        loaderAction.loadLibrary(libname, preload, preloadIgnoreError);    
-    }
+  /**
+   * Loads the library specified by libname, using the {@link LoaderAction} set by {@link #setLoadingAction(LoaderAction)}.<br>
+   * Optionally preloads the libraries specified by preload.<br>
+   * The implementation should ignore, if any library has been loaded already.<br>
+   * @param libname the library to load
+   * @param preload the libraries to load before loading the main library if not null
+   * @param preloadIgnoreError if true, errors during loading the preload-libraries should be ignored 
+   * @param cl optional ClassLoader, used to locate the library
+   */
+  protected static synchronized void loadLibrary(String libname, String[] preload, boolean preloadIgnoreError, ClassLoader cl) {
+      if (loaderAction != null) {
+          loaderAction.loadLibrary(libname, preload, preloadIgnoreError, cl);    
+      }
   }
 
   // private static final Class<?> customLauncherClass;
@@ -284,7 +303,7 @@ public class JNILibLoaderBase {
     customLoadLibraryMethod = loadLibraryMethod;
   }
 
-  private static void loadLibraryInternal(String libraryName) {
+  private static void loadLibraryInternal(String libraryName, ClassLoader cl) {
     // Note: special-casing JAWT which is built in to the JDK
     if (null!=customLoadLibraryMethod && !libraryName.equals("jawt")) {
         try {
@@ -305,22 +324,33 @@ public class JNILibLoaderBase {
         }
     } else {
       if(TempJarCache.isInitialized()) {
-          final String fullLibraryName = TempJarCache.findLibrary(libraryName);
-          if(null != fullLibraryName) {
+          final String libraryPath = TempJarCache.findLibrary(libraryName);
+          if(null != libraryPath) {
             if(DEBUG) {
-              System.err.println("JNILibLoaderBase: loadLibraryInternal("+libraryName+") -> System.load("+fullLibraryName+") (TempJarCache)");
+              System.err.println("JNILibLoaderBase: loadLibraryInternal("+libraryName+") -> System.load("+libraryPath+") (TempJarCache)");
             }
-            System.load(fullLibraryName);
+            System.load(libraryPath);
             return; // done
           } else if(DEBUG) {
             System.err.println("JNILibLoaderBase: loadLibraryInternal("+libraryName+") -> TempJarCache not mapped");
           }
       }
       // System.err.println("sun.boot.library.path=" + Debug.getProperty("sun.boot.library.path", false));
+      final String libraryPath = NativeLibrary.findLibrary(libraryName, cl);
       if(DEBUG) {
-          System.err.println("JNILibLoaderBase: loadLibraryInternal("+libraryName+") -> System.loadLibrary("+libraryName+")");
+          System.err.print("JNILibLoaderBase: loadLibraryInternal("+libraryName+"): CL: "+libraryPath);
+      }
+      if(null != libraryPath) {
+          if(DEBUG) {
+              System.err.println(" -> System.load("+libraryPath+")");
+          }
+          System.loadLibrary(libraryPath);
+      } else {
+          if(DEBUG) {
+              System.err.println(" -> System.loadLibrary("+libraryName+")");
+          }
+          System.loadLibrary(libraryName);          
       }
-      System.loadLibrary(libraryName);
     }
   }
 }
diff --git a/src/java/com/jogamp/common/os/DynamicLibraryBundle.java b/src/java/com/jogamp/common/os/DynamicLibraryBundle.java
index fc302e9..427f522 100755
--- a/src/java/com/jogamp/common/os/DynamicLibraryBundle.java
+++ b/src/java/com/jogamp/common/os/DynamicLibraryBundle.java
@@ -42,8 +42,8 @@ import com.jogamp.common.util.RunnableExecutor;
 /**
  * Provides bundling of:<br>
  * <ul>
- * <li>The to-be-glued native library, eg OpenGL32.dll. From hereon this is referred as the Tool.</li>
- * <li>The JNI glue-code native library, eg jogl_desktop.dll. From heron this is referred as the Glue</li>
+ * <li>The to-be-glued native library, eg OpenGL32.dll. From here on this is referred as the Tool.</li>
+ * <li>The JNI glue-code native library, eg jogl_desktop.dll. From here on this is referred as the Glue</li>
  * </ul><br>
  * An instance provides a complete {@link com.jogamp.common.os.DynamicLookupHelper}
  * to {@link com.jogamp.gluegen.runtime.ProcAddressTable#reset(com.jogamp.common.os.DynamicLookupHelper) reset}
@@ -52,7 +52,7 @@ import com.jogamp.common.util.RunnableExecutor;
  * <ul>
  *  <li> loads the Tool native library via
  *       {@link com.jogamp.common.os.NativeLibrary#open(java.lang.String, java.lang.ClassLoader, boolean) NativeLibrary's open method}</li>
- *  <li> loads the {@link com.jogamp.common.jvm.JNILibLoaderBase#loadLibrary(java.lang.String, java.lang.String[], boolean)  Glue native library}</li>
+ *  <li> loads the {@link com.jogamp.common.jvm.JNILibLoaderBase#loadLibrary(java.lang.String, java.lang.String[], boolean, ClassLoader)  Glue native library}</li>
  *  <li> resolves the Tool's {@link com.jogamp.common.os.DynamicLibraryBundleInfo#getToolGetProcAddressFuncNameList() GetProcAddress}. (optional)</li>
  * </ul>
  */
@@ -251,13 +251,13 @@ public class DynamicLibraryBundle implements DynamicLookupHelper {
         }
 
         toolLibLoadedNumber = 0;
-        ClassLoader loader = getClass().getClassLoader();
+        final ClassLoader cl = info.getClass().getClassLoader();
         NativeLibrary lib = null;
 
         for (i=0; i < toolLibNames.size(); i++) {    
             final List<String> libNames = toolLibNames.get(i);
             if( null != libNames && libNames.size() > 0 ) {
-                lib = loadFirstAvailable(libNames, loader, info.shallLinkGlobal());
+                lib = loadFirstAvailable(libNames, cl, info.shallLinkGlobal());
                 if ( null == lib ) {
                     if(DEBUG) {
                         System.err.println("Unable to load any Tool library of: "+libNames);
@@ -285,7 +285,7 @@ public class DynamicLibraryBundle implements DynamicLookupHelper {
             boolean ignoreError = true;
             boolean res;
             try {
-                res = GlueJNILibLoader.loadLibrary(libName, ignoreError);
+                res = GlueJNILibLoader.loadLibrary(libName, ignoreError, cl);
                 if(DEBUG && !res) {
                     System.err.println("Info: Could not load JNI/Glue library: "+libName);
                 }
@@ -375,8 +375,8 @@ public class DynamicLibraryBundle implements DynamicLookupHelper {
 
     /** Inherit access */
     static class GlueJNILibLoader extends JNILibLoaderBase {
-      protected static synchronized boolean loadLibrary(String libname, boolean ignoreError) {
-        return JNILibLoaderBase.loadLibrary(libname, ignoreError);
+      protected static synchronized boolean loadLibrary(String libname, boolean ignoreError, ClassLoader cl) {
+        return JNILibLoaderBase.loadLibrary(libname, ignoreError, cl);
       }
     }
 }
diff --git a/src/java/com/jogamp/common/os/NativeLibrary.java b/src/java/com/jogamp/common/os/NativeLibrary.java
index 69d69b6..d0b135e 100755
--- a/src/java/com/jogamp/common/os/NativeLibrary.java
+++ b/src/java/com/jogamp/common/os/NativeLibrary.java
@@ -299,10 +299,7 @@ public class NativeLibrary implements DynamicLookupHelper {
 
     // The idea to ask the ClassLoader to find the library is borrowed
     // from the LWJGL library
-    String clPath = getPathFromClassLoader(libName, loader);
-    if (DEBUG) {
-      System.err.println("NativeLibrary Class loader path to " + libName + ": " + clPath);
-    }
+    final String clPath = findLibrary(libName, loader);
     if (clPath != null) {
       paths.add(clPath);
     }
@@ -422,9 +419,10 @@ public class NativeLibrary implements DynamicLookupHelper {
 
   private static boolean initializedFindLibraryMethod = false;
   private static Method  findLibraryMethod = null;
-  private static String getPathFromClassLoader(final String libName, final ClassLoader loader) {
-    if (loader == null)
+  private static String findLibraryImpl(final String libName, final ClassLoader loader) {
+    if (loader == null) {
       return null;
+    }
     if (!initializedFindLibraryMethod) {
       AccessController.doPrivileged(new PrivilegedAction<Object>() {
           public Object run() {
@@ -460,4 +458,11 @@ public class NativeLibrary implements DynamicLookupHelper {
     }
     return null;
   }
+  public static String findLibrary(final String libName, final ClassLoader loader) {
+    final String res = findLibraryImpl(libName, loader);
+    if (DEBUG) {
+      System.err.println("NativeLibrary.findLibrary(<"+libName+">, "+loader+"): "+res);
+    }
+    return res;
+  }
 }
diff --git a/src/java/com/jogamp/common/os/Platform.java b/src/java/com/jogamp/common/os/Platform.java
index fa565a0..49ae512 100644
--- a/src/java/com/jogamp/common/os/Platform.java
+++ b/src/java/com/jogamp/common/os/Platform.java
@@ -378,9 +378,9 @@ public class Platform {
     private static void loadGlueGenRTImpl() {
         AccessController.doPrivileged(new PrivilegedAction<Object>() {
             public Object run() {
+              final ClassLoader cl = Platform.class.getClassLoader();
               if(USE_TEMP_JAR_CACHE && TempJarCache.initSingleton()) {
                   final String nativeJarName = libBaseName+"-natives-"+os_and_arch+".jar";
-                  final ClassLoader cl = Platform.class.getClassLoader();                
                   try {
                     final URL jarUrlRoot = JarUtil.getURLDirname(
                                         JarUtil.getJarSubURL(Platform.class.getName(), cl) );
@@ -391,7 +391,7 @@ public class Platform {
                     System.err.println("Catched: "+e0.getMessage());
                   }
               }
-              DynamicLibraryBundle.GlueJNILibLoader.loadLibrary(libBaseName, false);
+              DynamicLibraryBundle.GlueJNILibLoader.loadLibrary(libBaseName, false, cl);
               return null;
             }
         });
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/BindingJNILibLoader.java b/src/junit/com/jogamp/gluegen/test/junit/generation/BindingJNILibLoader.java
index 5fc2df7..23daa6d 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/BindingJNILibLoader.java
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/BindingJNILibLoader.java
@@ -36,7 +36,7 @@ public class BindingJNILibLoader extends JNILibLoaderBase {
   public static void loadBindingtest1p1() {
     AccessController.doPrivileged(new PrivilegedAction<Object>() {
       public Object run() {
-        loadLibrary("Bindingtest1p1", null, true);
+        loadLibrary("Bindingtest1p1", null, true, BindingJNILibLoader.class.getClassLoader());
         return null;
       }
     });
@@ -45,7 +45,7 @@ public class BindingJNILibLoader extends JNILibLoaderBase {
   public static void loadBindingtest1p2() {
     AccessController.doPrivileged(new PrivilegedAction<Object>() {
       public Object run() {
-        loadLibrary("Bindingtest1p2", null, true);
+        loadLibrary("Bindingtest1p2", null, true, BindingJNILibLoader.class.getClassLoader());
         return null;
       }
     });
-- 
cgit v1.2.3