diff options
author | Sven Gothel <[email protected]> | 2010-06-10 06:13:06 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-06-10 06:13:06 +0200 |
commit | 555091d37a9a44fb7c35479ddecfee358a559e90 (patch) | |
tree | 350a3b9b7f55db85dcf3a808f0249bcd0ab32a74 /src/java/com/jogamp | |
parent | 710d86d31cd278583ee3d74b36595f4148a72133 (diff) |
Adding DynamicLibraryBundle utility to bundle Tool and JNI native library loading and lookup
Add JNILibLoaderBase.loadLibrary(String libname, boolean ignoreError);
DynamicLibraryBundle provides Tool and JNI native library loading and lookup
New classes:
com.jogamp.common.os.DynamicLibraryBundle
com.jogamp.common.os.DynamicLibraryBundleInfo
com.jogamp.common.util.MiscUtils.java
Change: DEBUG/VERBOSE properties 'gluegen' -> 'jogamp'
Diffstat (limited to 'src/java/com/jogamp')
7 files changed, 522 insertions, 41 deletions
diff --git a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java index be5b1de..8d26bf4 100644 --- a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java +++ b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java @@ -45,7 +45,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.AccessController; import java.security.AccessControlContext; -import java.security.PrivilegedAction; import java.util.HashSet; import com.jogamp.common.impl.Debug; @@ -55,43 +54,56 @@ public class JNILibLoaderBase { public interface LoaderAction { /** - * Loads the library specified by libname. Optionally preloads the libraries specified by - * preload. The implementation should ignore, if the preload-libraries have already been - * loaded. + * Loads the library specified by libname.<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 + * @return true if library loaded successful + */ + boolean loadLibrary(String libname, boolean ignoreError); + + /** + * Loads the library specified by libname.<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 true, if errors during loading the preload-libraries should be ignored + * @param preloadIgnoreError if true, errors during loading the preload-libraries should be ignored */ - void loadLibrary(String libname, String[] preload, - boolean preloadIgnoreError); + void loadLibrary(String libname, String[] preload, boolean preloadIgnoreError); } private static class DefaultAction implements LoaderAction { - public void loadLibrary(String libname, String[] preload, boolean preloadIgnoreError) { - if (null!=preload) { - for (int i=0; i<preload.length; i++) { - if(!isLoaded(preload[i])) { - try { - loadLibraryInternal(preload[i]); - addLoaded(preload[i]); - if(DEBUG) { - System.err.println("NativeLibLoaderBase preloaded "+preload[i]); - } - } catch (UnsatisfiedLinkError e) { - if(DEBUG) { - e.printStackTrace(); - } - if (!preloadIgnoreError && e.getMessage().indexOf("already loaded") < 0) { - throw e; - } - } + public boolean loadLibrary(String libname, boolean ignoreError) { + boolean res = true; + if(!isLoaded(libname)) { + try { + loadLibraryInternal(libname); + addLoaded(libname); + if(DEBUG) { + System.err.println("JNILibLoaderBase loaded "+libname); + } + } catch (UnsatisfiedLinkError e) { + res = false; + if(DEBUG) { + e.printStackTrace(); + } + if (!ignoreError && e.getMessage().indexOf("already loaded") < 0) { + throw e; + } } - } } - loadLibraryInternal(libname); - addLoaded(libname); - if(DEBUG) { - System.err.println("NativeLibLoaderBase loaded "+libname); + return res; + } + + public void loadLibrary(String libname, String[] preload, boolean preloadIgnoreError) { + if(!isLoaded(libname)) { + if (null!=preload) { + for (int i=0; i<preload.length; i++) { + loadLibrary(preload[i], preloadIgnoreError); + } + } + loadLibrary(libname, false); } } } @@ -106,7 +118,7 @@ public class JNILibLoaderBase { public static void addLoaded(String libName) { loaded.add(libName); if(DEBUG) { - System.err.println("NativeLibLoaderBase Loaded Native Library: "+libName); + System.err.println("JNILibLoaderBase Loaded Native Library: "+libName); } } @@ -122,14 +134,19 @@ public class JNILibLoaderBase { loaderAction = action; } - protected static synchronized void loadLibrary(String libname, String[] preload, - boolean preloadIgnoreError) { - if (loaderAction != null && !isLoaded(libname)) - { - loaderAction.loadLibrary(libname, preload, preloadIgnoreError); + protected static synchronized boolean loadLibrary(String libname, boolean ignoreError) { + if (loaderAction != null) { + return loaderAction.loadLibrary(libname, ignoreError); } + return false; } + protected static synchronized void loadLibrary(String libname, String[] preload, boolean preloadIgnoreError) { + if (loaderAction != null) { + loaderAction.loadLibrary(libname, preload, preloadIgnoreError); + } + } + private static final Class customLauncherClass; private static final Method customLoadLibraryMethod; diff --git a/src/java/com/jogamp/common/os/DynamicLibraryBundle.java b/src/java/com/jogamp/common/os/DynamicLibraryBundle.java new file mode 100755 index 0000000..8e138ef --- /dev/null +++ b/src/java/com/jogamp/common/os/DynamicLibraryBundle.java @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2010, Sven Gothel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sven Gothel nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Sven Gothel BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jogamp.common.os; + +import java.util.*; +import java.security.*; + +import com.jogamp.common.jvm.JNILibLoaderBase; +import com.jogamp.common.util.MiscUtils; + +/** + * 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> + * </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 lookup)} + * the {@link com.jogamp.gluegen.runtime.ProcAddressTable}.<br> + * At construction, it loads the Tool native library, loads Glue native library via + * {@link com.jogamp.common.os.DynamicLibraryBundleInfo#loadJNILibrary()} + * and resolves the optional Tool's <pre>GetProcAddress</pre> using {@link com.jogamp.common.os.DynamicLibraryBundleInfo#getToolGetProcAddressFuncNameList()}. + */ +public class DynamicLibraryBundle implements DynamicLookupHelper { + protected static final boolean DEBUG = NativeLibrary.DEBUG; + protected static final boolean DEBUG_LOOKUP = NativeLibrary.DEBUG_LOOKUP; + + private DynamicLibraryBundleInfo info; + + private List/*<List<String>>*/ toolLibNames; + private boolean[] toolLibLoaded; + private int toolLibLoadedNumber; + protected List/*<NativeLibrary>*/ nativeLibraries; + + private List/*<String>*/ glueLibNames; + private boolean[] glueLibLoaded; + private int glueLibLoadedNumber; + + private long toolGetProcAddressHandle; + private HashSet toolGetProcAddressFuncNameSet; + private List toolGetProcAddressFuncNameList; + + public DynamicLibraryBundle(DynamicLibraryBundleInfo info) { + if(null==info) { + throw new RuntimeException("Null DynamicLibraryBundleInfo"); + } + this.info = info; + if(DEBUG) { + System.out.println("DynamicLibraryBundle.init start with: "+info.getClass().getName()); + } + nativeLibraries = new ArrayList(); + toolLibNames = info.getToolLibNames(); + glueLibNames = info.getGlueLibNames(); + loadLibraries(); + toolGetProcAddressFuncNameList = info.getToolGetProcAddressFuncNameList(); + if(null!=toolGetProcAddressFuncNameList) { + toolGetProcAddressFuncNameSet = new HashSet(toolGetProcAddressFuncNameList); + toolGetProcAddressHandle = getToolGetProcAddressHandle(); + } else { + toolGetProcAddressFuncNameSet = new HashSet(); + toolGetProcAddressHandle = 0; + } + if(DEBUG) { + System.out.println("DynamicLibraryBundle.init Summary: "+info.getClass().getName()); + System.out.println(" toolGetProcAddressFuncNameList: "+MiscUtils.toString(toolGetProcAddressFuncNameList)); + System.out.println(" Tool Lib Names : "+MiscUtils.toString(toolLibNames)); + System.out.println(" Tool Lib Loaded: "+getToolLibLoadedNumber()+"/"+getToolLibNumber()+", complete "+isToolLibComplete()); + System.out.println(" Glue Lib Names : "+MiscUtils.toString(glueLibNames)); + System.out.println(" Glue Lib Loaded: "+getGlueLibLoadedNumber()+"/"+getGlueLibNumber()+", complete "+isGlueLibComplete()); + System.out.println(" All Complete: "+isLibComplete()); + } + } + + public final boolean isLibComplete() { + return isToolLibComplete() && isGlueLibComplete() ; + } + + public final int getToolLibNumber() { + return toolLibNames.size(); + } + + public final int getToolLibLoadedNumber() { + return toolLibLoadedNumber; + } + + public final boolean isToolLibComplete() { + return getToolLibNumber() == getToolLibLoadedNumber(); + } + + public final boolean isToolLibLoaded() { + return 0 < toolLibLoadedNumber; + } + + public final boolean isToolLibLoaded(int i) { + if(0 <= i && i < toolLibLoaded.length) { + return toolLibLoaded[i]; + } + return false; + } + + public final int getGlueLibNumber() { + return glueLibNames.size(); + } + + public final int getGlueLibLoadedNumber() { + return glueLibLoadedNumber; + } + + public final boolean isGlueLibComplete() { + return getGlueLibNumber() == getGlueLibLoadedNumber(); + } + + public final boolean isGlueLibLoaded(int i) { + if(0 <= i && i < glueLibLoaded.length) { + return glueLibLoaded[i]; + } + return false; + } + + public final DynamicLibraryBundleInfo getBundleInfo() { return info; } + + protected long getToolGetProcAddressHandle() { + if(!isToolLibLoaded()) { + return 0; + } + long aptr = 0; + for(Iterator iter=toolGetProcAddressFuncNameList.iterator(); 0==aptr && iter.hasNext(); ) { + String name = (String) iter.next(); + aptr = dynamicLookupFunctionOnLibs(name); + if(DEBUG) { + System.out.println("getToolGetProcAddressHandle: "+name+" -> 0x"+Long.toHexString(aptr)); + } + } + return aptr; + } + + protected NativeLibrary loadFirstAvailable(List/*<String>*/ libNames, ClassLoader loader, boolean global) { + for (Iterator iter = libNames.iterator(); iter.hasNext(); ) { + NativeLibrary lib = NativeLibrary.open((String) iter.next(), loader, global); + if (lib != null) { + return lib; + } + } + return null; + } + + private void loadLibraries() { + if( null == toolLibNames || toolLibNames.size() == 0) { + if(DEBUG) { + System.out.println("No Tool native library names given"); + } + return; + } + + if( null == glueLibNames || glueLibNames.size() == 0 ) { + if(DEBUG) { + System.out.println("No Glue native library names given"); + } + return; + } + + toolLibLoadedNumber = 0; + int i; + toolLibLoaded = new boolean[toolLibNames.size()]; + for(i=0; i<toolLibNames.size(); i++) { + toolLibLoaded[i] = false; + } + + glueLibLoaded = new boolean[glueLibNames.size()]; + for(i=0; i<glueLibNames.size(); i++) { + glueLibLoaded[i] = false; + } + + ClassLoader loader = getClass().getClassLoader(); + NativeLibrary lib = null; + + i=0; + for(Iterator iter = toolLibNames.iterator(); iter.hasNext(); i++) { + Object listObj = iter.next(); + List/*<String>*/ libNames = null; + if(listObj instanceof List) { + libNames = (List) listObj; + } else if(listObj instanceof String) { + libNames = new ArrayList(); + libNames.add((String)listObj); + } else { + throw new RuntimeException("List element "+i+" must be either a List or String: "+MiscUtils.toString(toolLibNames)); + } + if( null != libNames && libNames.size() > 0 ) { + lib = loadFirstAvailable(libNames, loader, info.shallLinkGlobal()); + if ( null == lib ) { + if(DEBUG) { + System.out.println("Unable to load any Tool library of: "+MiscUtils.toString(libNames)); + } + } else { + nativeLibraries.add(lib); + toolLibLoaded[i]=true; + toolLibLoadedNumber++; + if(DEBUG) { + System.out.println("Loaded Tool library: "+lib); + } + } + } + } + if( !isToolLibLoaded() ) { + if(DEBUG) { + System.out.println("No Tool libraries loaded"); + } + return; + } + + glueLibLoadedNumber = 0; + i=0; + for(Iterator iter = glueLibNames.iterator(); iter.hasNext(); i++) { + String libName = (String) iter.next(); + boolean ignoreError = true; + boolean res; + try { + res = GlueJNILibLoaderBase.loadLibrary(libName, ignoreError); + if(DEBUG && !res) { + System.out.println("Info: Could not load JNI/Glue library: "+libName); + } + } catch (UnsatisfiedLinkError e) { + res = false; + if(DEBUG) { + System.out.println("Unable to load JNI/Glue library: "+libName); + e.printStackTrace(); + } + } + glueLibLoaded[i] = res; + if(res) { + glueLibLoadedNumber++; + } + } + } + + private long dynamicLookupFunctionOnLibs(String funcName) { + if(!isToolLibLoaded() || null==funcName) { + if(DEBUG_LOOKUP && !isToolLibLoaded()) { + System.err.println("Lookup-Native: <" + funcName + "> ** FAILED ** Tool native library not loaded"); + } + return 0; + } + long addr = 0; + NativeLibrary lib = null; + + if(info.shallLookupGlobal()) { + // Try a global symbol lookup first .. + addr = NativeLibrary.dynamicLookupFunctionGlobal(funcName); + } + // Look up this function name in all known libraries + for (Iterator iter = nativeLibraries.iterator(); 0==addr && iter.hasNext(); ) { + lib = (NativeLibrary) iter.next(); + addr = lib.dynamicLookupFunction(funcName); + } + if(DEBUG_LOOKUP) { + String libName = ( null == lib ) ? "GLOBAL" : lib.toString(); + if(0!=addr) { + System.err.println("Lookup-Native: <" + funcName + "> 0x" + Long.toHexString(addr) + " in lib " + libName ); + } else { + System.err.println("Lookup-Native: <" + funcName + "> ** FAILED ** in libs " + MiscUtils.toString(nativeLibraries)); + } + } + return addr; + } + + public long dynamicLookupFunction(String funcName) { + if(!isToolLibLoaded() || null==funcName) { + if(DEBUG_LOOKUP && !isToolLibLoaded()) { + System.err.println("Lookup: <" + funcName + "> ** FAILED ** Tool native library not loaded"); + } + return 0; + } + + if(toolGetProcAddressFuncNameSet.contains(funcName)) { + return toolGetProcAddressHandle; + } + + long addr = 0; + + if(0 != toolGetProcAddressHandle) { + addr = info.toolDynamicLookupFunction(toolGetProcAddressHandle, funcName); + if(DEBUG_LOOKUP) { + if(0!=addr) { + System.err.println("Lookup-Tool: <"+funcName+"> 0x"+Long.toHexString(addr)); + } + } + } + if(0==addr) { + addr = dynamicLookupFunctionOnLibs(funcName); + } + return addr; + } + + /** Inherit access */ + static class GlueJNILibLoaderBase extends JNILibLoaderBase { + protected static synchronized boolean loadLibrary(String libname, boolean ignoreError) { + return JNILibLoaderBase.loadLibrary(libname, ignoreError); + } + } +} + diff --git a/src/java/com/jogamp/common/os/DynamicLibraryBundleInfo.java b/src/java/com/jogamp/common/os/DynamicLibraryBundleInfo.java new file mode 100644 index 0000000..37ca538 --- /dev/null +++ b/src/java/com/jogamp/common/os/DynamicLibraryBundleInfo.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2010, Sven Gothel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sven Gothel nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Sven Gothel BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jogamp.common.os; + +import java.util.*; +import java.security.*; + +public interface DynamicLibraryBundleInfo { + public static final boolean DEBUG = DynamicLibraryBundle.DEBUG; + + /** @return a list of Tool library names or alternative library name lists.<br> + * <ul> + * <li>GL/GLU example Unix: [ [ "libGL.so.1", "libGL.so", "GL" ], [ "libGLU.so", "GLU" ] ] </li> + * <li>GL/GLU example Windows: [ "OpenGL32", "GLU32" ] </li> + * <li>Cg/CgGL example: [ [ "libCg.so", "Cg" ], [ "libCgGL.so", "CgGL" ] ] </li> + * </pre> + */ + public List getToolLibNames(); + + /** @return a list of Glue library names.<br> + * <ul> + * <li>GL: [ "nativewindow_x11", "jogl_gl2es12", "jogl_desktop" ] </li> + * <li>NEWT: [ "nativewindow_x11", "newt" ] </li> + * <li>Cg: [ "nativewindow_x11", "jogl_cg" ] </li> + * </ul><br> + * Only the last entry is crucial, ie all other are optional preload dependencies and may generate errors, + * which are ignored. + */ + public List/*<String>*/ getGlueLibNames(); + + /** May return the native libraries <pre>GetProcAddressFunc</pre> names, the first found function is being used.<br> + * This could be eg: <pre> glXGetProcAddressARB, glXGetProcAddressARB </pre>.<br> + * If your Tool does not has this facility, just return null. + */ + public List getToolGetProcAddressFuncNameList() ; + + /** May implement the lookup function using the Tools facility.<br> + * The actual function pointer is provided to allow proper bootstrapping of the ProcAddressTable.<br> + */ + public long toolDynamicLookupFunction(long toolGetProcAddressHandle, String funcName); + + /** @return true if the native library symbols shall be made available for symbol resolution of subsequently loaded libraries. */ + public boolean shallLinkGlobal(); + + /** @return true if the dynamic symbol lookup shall happen system wide, over all loaded libraries. Otherwise only the loaded native libraries are used for lookup, which shall be the default. */ + public boolean shallLookupGlobal(); + +} + + diff --git a/src/java/com/jogamp/common/os/NativeLibrary.java b/src/java/com/jogamp/common/os/NativeLibrary.java index 897e240..97aabae 100755 --- a/src/java/com/jogamp/common/os/NativeLibrary.java +++ b/src/java/com/jogamp/common/os/NativeLibrary.java @@ -62,7 +62,8 @@ public class NativeLibrary implements DynamicLookupHelper { private static final int WINDOWS = 1; private static final int UNIX = 2; private static final int MACOSX = 3; - private static boolean DEBUG; + protected static boolean DEBUG; + protected static boolean DEBUG_LOOKUP; private static int platform; private static DynamicLinker dynLink; private static String[] prefixes; @@ -81,7 +82,8 @@ public class NativeLibrary implements DynamicLookupHelper { platform = UNIX; } - DEBUG = (System.getProperty("gluegen.debug.NativeLibrary") != null); + DEBUG = (System.getProperty("jogamp.debug.NativeLibrary") != null); + DEBUG_LOOKUP = (System.getProperty("jogamp.debug.NativeLibrary.Lookup") != null); return null; } diff --git a/src/java/com/jogamp/common/os/WindowsDynamicLinkerImpl.java b/src/java/com/jogamp/common/os/WindowsDynamicLinkerImpl.java index 935f386..7bbfe23 100755 --- a/src/java/com/jogamp/common/os/WindowsDynamicLinkerImpl.java +++ b/src/java/com/jogamp/common/os/WindowsDynamicLinkerImpl.java @@ -11,7 +11,7 @@ public class WindowsDynamicLinkerImpl implements DynamicLinker { static { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { - DEBUG = (System.getProperty("gluegen.debug.NativeLibrary") != null); + DEBUG = (System.getProperty("jogamp.debug.NativeLibrary") != null); return null; } }); diff --git a/src/java/com/jogamp/common/util/MiscUtils.java b/src/java/com/jogamp/common/util/MiscUtils.java new file mode 100644 index 0000000..dd32951 --- /dev/null +++ b/src/java/com/jogamp/common/util/MiscUtils.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2010, Sven Gothel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sven Gothel nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Sven Gothel BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jogamp.common.util; + +import java.util.*; + +public class MiscUtils { + + public static StringBuffer append(StringBuffer sb, List list) { + sb.append("["); + if(null!=list&&list.size()>0) { + boolean comma = false; + for(Iterator iter=list.iterator(); iter.hasNext(); ) { + if(comma) { sb.append(", "); } + Object o = iter.next(); + if(o instanceof List) { + sb = append(sb, (List)o); + } else { + sb.append(o); + } + comma = true; + } + } + sb.append("]"); + return sb; + } + + public static String toString(List list) { + return append(new StringBuffer(), list).toString(); + } +} + diff --git a/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java b/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java index 9a05fce..f0be20f 100644 --- a/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java +++ b/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java @@ -65,9 +65,9 @@ public abstract class ProcAddressTable { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { - DEBUG = (System.getProperty("gluegen.debug.ProcAddressHelper") != null); + DEBUG = (System.getProperty("jogamp.debug.ProcAddressHelper") != null); if (DEBUG) { - DEBUG_PREFIX = System.getProperty("gluegen.debug.ProcAddressHelper.prefix"); + DEBUG_PREFIX = System.getProperty("jogamp.debug.ProcAddressHelper.prefix"); } return null; } @@ -90,6 +90,9 @@ public abstract class ProcAddressTable { public void reset(DynamicLookupHelper lookup) throws RuntimeException { + if(null==lookup) { + throw new RuntimeException("Passed null DynamicLookupHelper"); + } Class tableClass = getClass(); Field[] fields = tableClass.getFields(); |