diff options
author | Sven Gothel <[email protected]> | 2013-01-30 15:35:40 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-01-30 15:35:40 +0100 |
commit | 00c9fa8f2d69d15a2e4183e127b543a92fb5f4b8 (patch) | |
tree | 87645915a69c3c585cad008e0eee52ecf88b4524 | |
parent | be6c4158cf901af01be370b31e5bec368a51b2d5 (diff) |
GlueGen: NativeLibrary Fix, JNILibLoaderBase Enhancement
- NativeLibrary Fix
- enumerateLibraryPaths(..):
- Properly iterate through all prefix _and_ suffix.
- Make public for JNILibLoaderBase.loadLibraryInternal(..)
- isValidNativeLibraryName(..):
- Stop iterating through prefix, if previously found
but suffix doesn't match.
- JNILibLoaderBase.loadLibraryInternal(..) Enhancement
- Mark customLibLoader FIXME: remove (we will get rid of jnlp.launcher.class)
- If System.load(TempJarCache) and System.loadLibrary(plainLibName) fails,
use NativeLibrary.enumerateLibraryPaths() w/ System.load(..) as last resort.
Tested on Linux x86_64 Java6 and OSX Java7 manually, no regressions expected.
-rw-r--r-- | make/build-test.xml | 4 | ||||
-rwxr-xr-x | make/scripts/runtest.sh | 8 | ||||
-rw-r--r-- | src/java/com/jogamp/common/jvm/JNILibLoaderBase.java | 104 | ||||
-rwxr-xr-x | src/java/com/jogamp/common/os/NativeLibrary.java | 112 |
4 files changed, 142 insertions, 86 deletions
diff --git a/make/build-test.xml b/make/build-test.xml index 9810f06..7f2c521 100644 --- a/make/build-test.xml +++ b/make/build-test.xml @@ -417,7 +417,7 @@ chmod 644 ${results}/* \${line.separator} <mkdir dir="${build}/test/results"/> </target> - <target name="junit.run.local.d32" if="isOSX"> + <target name="junit.run.local.osx.d32" if="isOSX"> <var name="jvmDataModel.arg" unset="true"/> <var name="jvmDataModel.arg" value="-d32"/> @@ -433,7 +433,7 @@ chmod 644 ${results}/* \${line.separator} <var name="jvmDataModel.arg" value="-d64"/> </target> - <target name="junit.run.tests" depends="junit.run.local.d32, junit.run.local, junit.run.remote.ssh, junit.run.remote.adb"/> + <target name="junit.run.tests" depends="junit.run.local.osx.d32, junit.run.local, junit.run.remote.ssh, junit.run.remote.adb"/> <target name="junit.run.if.enabled" unless="junit.is.disabled"> <antcall target="junit.run.tests" inheritRefs="true" inheritAll="true"/> diff --git a/make/scripts/runtest.sh b/make/scripts/runtest.sh index d01867f..13f4aa0 100755 --- a/make/scripts/runtest.sh +++ b/make/scripts/runtest.sh @@ -47,7 +47,7 @@ rm -f $LOG #D_ARGS="-Djogamp.debug.IOUtil -Djogamp.debug.JNILibLoader -Djogamp.debug.TempFileCache -Djogamp.debug.JarUtil -Djava.io.tmpdir=/run/tmp" #D_ARGS="-Djogamp.debug.IOUtil -Djogamp.debug.JNILibLoader -Djogamp.debug.TempFileCache -Djogamp.debug.JarUtil -Djogamp.debug.TempJarCache" #D_ARGS="-Djogamp.debug.JNILibLoader -Djogamp.gluegen.UseTempJarCache=false" -#D_ARGS="-Djogamp.debug.JNILibLoader" +D_ARGS="-Djogamp.debug.JNILibLoader" #D_ARGS="-Djogamp.debug.Lock" #D_ARGS="-Djogamp.debug.Lock -Djogamp.debug.Lock.TraceLock" #D_ARGS="-Djogamp.debug.Lock.TraceLock" @@ -60,6 +60,8 @@ function onetest() { #CLASSPATH=lib/junit.jar:$ANT_JARS:$builddir/../make/lib/TestJarsInJar.jar:$builddir/classes:$builddir/test/build/classes #libspath=$builddir/obj:$builddir/test/build/natives: LD_LIBRARY_PATH=$libspath:$LD_LIBRARY_PATH + DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH + export LD_LIBRARY_PATH DYLD_LIBRARY_PATH echo LD_LIBRARY_PATH $LD_LIBRARY_PATH echo CLASSPATH $CLASSPATH echo java -cp $CLASSPATH $D_ARGS -Djava.library.path=$libspath $clazz @@ -67,7 +69,7 @@ function onetest() { echo } -onetest com.jogamp.common.GlueGenVersion 2>&1 | tee -a $LOG +#onetest com.jogamp.common.GlueGenVersion 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestSystemPropsAndEnvs 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestVersionInfo 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestVersionNumber 2>&1 | tee -a $LOG @@ -87,7 +89,7 @@ onetest com.jogamp.common.GlueGenVersion 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.PCPPTest 2>&1 | tee -a $LOG #onetest com.jogamp.common.nio.TestPointerBufferEndian 2>&1 | tee -a $LOG #onetest com.jogamp.common.nio.TestStructAccessorEndian 2>&1 | tee -a $LOG -#onetest com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter 2>&1 | tee -a $LOG +onetest com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestPlatform01 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestRunnableTask01 2>&1 | tee -a $LOG diff --git a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java index 94f451e..d0d8003 100644 --- a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java +++ b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java @@ -47,6 +47,8 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Arrays; import java.util.HashSet; +import java.util.Iterator; +import java.util.List; import com.jogamp.common.os.NativeLibrary; import com.jogamp.common.util.JarUtil; @@ -345,7 +347,7 @@ public class JNILibLoaderBase { } } - // private static final Class<?> customLauncherClass; + // private static final Class<?> customLauncherClass; // FIXME: remove private static final Method customLoadLibraryMethod; static { @@ -354,6 +356,7 @@ public class JNILibLoaderBase { final Method loadLibraryMethod = AccessController.doPrivileged(new PrivilegedAction<Method>() { public Method run() { + // FIXME: remove final boolean usingJNLPAppletLauncher = Debug.getBooleanProperty(sunAppletLauncherProperty, true); Class<?> launcherClass = null; @@ -380,8 +383,7 @@ public class JNILibLoaderBase { launcherClass = null; } } - } - + } if(null==launcherClass) { String launcherClassName = PropertyAccess.getProperty("jnlp.launcher.class", false, null); if(null!=launcherClassName) { @@ -406,41 +408,77 @@ public class JNILibLoaderBase { } 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 { - customLoadLibraryMethod.invoke(null, new Object[] { libraryName }); - } catch (Exception e) { - Throwable t = e; - if (t instanceof InvocationTargetException) { - t = ((InvocationTargetException) t).getTargetException(); - } - if (t instanceof Error) { - throw (Error) t; - } - if (t instanceof RuntimeException) { - throw (RuntimeException) t; - } - // Throw UnsatisfiedLinkError for best compatibility with System.loadLibrary() - throw (UnsatisfiedLinkError) new UnsatisfiedLinkError("can not load library "+libraryName).initCause(e); - } - } else { - // System.err.println("sun.boot.library.path=" + Debug.getProperty("sun.boot.library.path", false)); - final String libraryPath = NativeLibrary.findLibrary(libraryName, cl); // implicit TempJarCache usage if used/initialized - if(DEBUG) { - System.err.print("JNILibLoaderBase: loadLibraryInternal("+libraryName+"): CL: "+libraryPath); - } - if(null != libraryPath) { + // Note: special-casing JAWT which is built in to the JDK + int mode = 0; // 1 - custom, 2 - System.load( TempJarCache ), 3 - System.loadLibrary( name ), 4 - System.load( enumLibNames ) + if (null!=customLoadLibraryMethod && !libraryName.equals("jawt")) { + // FIXME: remove if(DEBUG) { - System.err.println(" -> System.load("+libraryPath+")"); + System.err.println("JNILibLoaderBase: customLoad("+libraryName+") - mode 1"); + } + try { + customLoadLibraryMethod.invoke(null, new Object[] { libraryName }); + mode = 1; + } catch (Exception e) { + Throwable t = e; + if (t instanceof InvocationTargetException) { + t = ((InvocationTargetException) t).getTargetException(); + } + if (t instanceof Error) { + throw (Error) t; + } + if (t instanceof RuntimeException) { + throw (RuntimeException) t; + } + // Throw UnsatisfiedLinkError for best compatibility with System.loadLibrary() + throw (UnsatisfiedLinkError) new UnsatisfiedLinkError("can not load library "+libraryName).initCause(e); } - System.load(libraryPath); } else { + // System.err.println("sun.boot.library.path=" + Debug.getProperty("sun.boot.library.path", false)); + final String libraryPath = NativeLibrary.findLibrary(libraryName, cl); // implicit TempJarCache usage if used/initialized if(DEBUG) { - System.err.println(" -> System.loadLibrary("+libraryName+")"); + System.err.println("JNILibLoaderBase: loadLibraryInternal("+libraryName+"), TempJarCache: "+libraryPath); + } + if(null != libraryPath) { + if(DEBUG) { + System.err.println("JNILibLoaderBase: System.load("+libraryPath+") - mode 2"); + } + System.load(libraryPath); + mode = 2; + } else { + if(DEBUG) { + System.err.println("JNILibLoaderBase: System.loadLibrary("+libraryName+") - mode 3"); + } + try { + System.loadLibrary(libraryName); + mode = 3; + } catch (UnsatisfiedLinkError ex1) { + if(DEBUG) { + System.err.println("ERROR (retry w/ enumLibPath) - "+ex1.getMessage()); + } + List<String> possiblePaths = NativeLibrary.enumerateLibraryPaths(libraryName, libraryName, libraryName, true, cl); + // Iterate down these and see which one if any we can actually find. + for (Iterator<String> iter = possiblePaths.iterator(); 0 == mode && iter.hasNext(); ) { + String path = iter.next(); + if (DEBUG) { + System.err.println("JNILibLoaderBase: System.load("+path+") - mode 4"); + } + try { + System.load(path); + mode = 4; + } catch (UnsatisfiedLinkError ex2) { + if(DEBUG) { + System.err.println("n/a - "+ex2.getMessage()); + } + if(!iter.hasNext()) { + throw ex2; + } + } + } + } } - System.loadLibrary(libraryName); } - } + if(DEBUG) { + System.err.println("JNILibLoaderBase: loadLibraryInternal("+libraryName+"): OK - mode "+mode); + } } } diff --git a/src/java/com/jogamp/common/os/NativeLibrary.java b/src/java/com/jogamp/common/os/NativeLibrary.java index f5265af..49ec860 100755 --- a/src/java/com/jogamp/common/os/NativeLibrary.java +++ b/src/java/com/jogamp/common/os/NativeLibrary.java @@ -174,13 +174,13 @@ public class NativeLibrary implements DynamicLookupHelper { macOSXLibName, searchSystemPathFirst, loader); + Platform.initSingleton(); // loads native gluegen-rt library // Iterate down these and see which one if any we can actually find. for (Iterator<String> iter = possiblePaths.iterator(); iter.hasNext(); ) { String path = iter.next(); if (DEBUG) { System.err.println("NativeLibrary.open(): Trying to load " + path); } - Platform.initSingleton(); // loads native gluegen-rt library long res; if(global) { res = dynLink.openLibraryGlobal(path, DEBUG); @@ -254,18 +254,22 @@ public class NativeLibrary implements DynamicLookupHelper { * @return basename of libName w/o path, ie. /usr/lib/libDrinkBeer.so -> DrinkBeer on Unix systems, but null on Windows. */ public static String isValidNativeLibraryName(String libName, boolean isLowerCaseAlready) { - libName = IOUtil.getBasename(libName); - final String libNameLC = isLowerCaseAlready ? libName : libName.toLowerCase(); - for(int i=0; i<prefixes.length; i++) { - if (libNameLC.startsWith(prefixes[i])) { - for(int j=0; j<suffixes.length; j++) { - if (libNameLC.endsWith(suffixes[j])) { - final int s = prefixes[i].length(); - final int e = suffixes[j].length(); - return libName.substring(s, libName.length()-e); - } + final String libBaseName = IOUtil.getBasename(libName); + final String libBaseNameLC = isLowerCaseAlready ? libBaseName : libBaseName.toLowerCase(); + int prefixIdx = -1; + for(int i=0; i<prefixes.length && 0 > prefixIdx; i++) { + if (libBaseNameLC.startsWith(prefixes[i])) { + prefixIdx = i; + } + } + if( 0 <= prefixIdx ) { + for(int i=0; i<suffixes.length; i++) { + if (libBaseNameLC.endsWith(suffixes[i])) { + final int s = prefixes[prefixIdx].length(); + final int e = suffixes[i].length(); + return libBaseName.substring(s, libBaseName.length()-e); } - } + } } return null; } @@ -273,7 +277,7 @@ public class NativeLibrary implements DynamicLookupHelper { /** Given the base library names (no prefixes/suffixes) for the various platforms, enumerate the possible locations and names of the indicated native library on the system. */ - private static List<String> enumerateLibraryPaths(String windowsLibName, + public static List<String> enumerateLibraryPaths(String windowsLibName, String unixLibName, String macOSXLibName, boolean searchSystemPathFirst, @@ -372,46 +376,58 @@ public class NativeLibrary implements DynamicLookupHelper { } private static String[] buildNames(String libName) { - // If the library name already has the prefix / suffix added - // (principally because we want to force a version number on Unix - // operating systems) then just return the library name. - if (libName.startsWith(prefixes[0])) { - if (libName.endsWith(suffixes[0])) { - return new String[] { libName }; + // If the library name already has the prefix / suffix added + // (principally because we want to force a version number on Unix + // operating systems) then just return the library name. + final String libBaseNameLC = IOUtil.getBasename(libName).toLowerCase(); + + int prefixIdx = -1; + for(int i=0; i<prefixes.length && 0 > prefixIdx; i++) { + if (libBaseNameLC.startsWith(prefixes[i])) { + prefixIdx = i; + } } - - int idx = libName.indexOf(suffixes[0]); - boolean ok = true; - if (idx >= 0) { - // Check to see if everything after it is a Unix version number - for (int i = idx + suffixes[0].length(); - i < libName.length(); - i++) { - char c = libName.charAt(i); - if (!(c == '.' || (c >= '0' && c <= '9'))) { - ok = false; - break; + if( 0 <= prefixIdx ) { + for(int i=0; i<suffixes.length; i++) { + if (libBaseNameLC.endsWith(suffixes[i])) { + return new String[] { libName }; + } + } + int suffixIdx = -1; + for(int i=0; i<suffixes.length && 0 > suffixIdx; i++) { + suffixIdx = libBaseNameLC.indexOf(suffixes[i]); + } + boolean ok = true; + if (suffixIdx >= 0) { + // Check to see if everything after it is a Unix version number + for (int i = suffixIdx + suffixes[0].length(); + i < libName.length(); + i++) { + char c = libName.charAt(i); + if (!(c == '.' || (c >= '0' && c <= '9'))) { + ok = false; + break; + } + } + if (ok) { + return new String[] { libName }; + } } - } - if (ok) { - return new String[] { libName }; - } } - } - String[] res = new String[prefixes.length * suffixes.length + - ( PlatformPropsImpl.OS_TYPE == Platform.OSType.MACOS ? 1 : 0 )]; - int idx = 0; - for (int i = 0; i < prefixes.length; i++) { - for (int j = 0; j < suffixes.length; j++) { - res[idx++] = prefixes[i] + libName + suffixes[j]; + String[] res = new String[prefixes.length * suffixes.length + + ( PlatformPropsImpl.OS_TYPE == Platform.OSType.MACOS ? 1 : 0 )]; + int idx = 0; + for (int i = 0; i < prefixes.length; i++) { + for (int j = 0; j < suffixes.length; j++) { + res[idx++] = prefixes[i] + libName + suffixes[j]; + } } - } - if (PlatformPropsImpl.OS_TYPE == Platform.OSType.MACOS) { - // Plain library-base-name in Framework folder - res[idx++] = libName; - } - return res; + if (PlatformPropsImpl.OS_TYPE == Platform.OSType.MACOS) { + // Plain library-base-name in Framework folder + res[idx++] = libName; + } + return res; } private static void addPaths(String path, String[] baseNames, List<String> paths) { |