From 710d86d31cd278583ee3d74b36595f4148a72133 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 5 Jun 2010 00:03:49 +0200 Subject: Minor additions to nio/Buffers, util/IntIntHashMap and os/NativeLibrary Buffers add 'float[] getFloatArray(double[])' conversion, ready to replace all JOGL InternalBufferUtil's. NativeLibrary/DynamicLinker add global lookup method allowing Unices and OSX to lookup a symbol globally. However, this is not recommended, due to the lookup costs. Windows is not supported here. Primitive type HashMap's (IntIntHashMap): Added putAll() --- src/java/com/jogamp/common/os/NativeLibrary.java | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/java/com/jogamp/common/os/NativeLibrary.java') diff --git a/src/java/com/jogamp/common/os/NativeLibrary.java b/src/java/com/jogamp/common/os/NativeLibrary.java index 2de8bc9..897e240 100755 --- a/src/java/com/jogamp/common/os/NativeLibrary.java +++ b/src/java/com/jogamp/common/os/NativeLibrary.java @@ -122,6 +122,10 @@ public class NativeLibrary implements DynamicLookupHelper { this.libraryPath = libraryPath; } + public String toString() { + return "NativeLibrary[" + libraryPath + ", 0x" + Long.toHexString(libraryHandle) + "]"; + } + /** Opens the given native library, assuming it has the same base name on all platforms, looking first in the system's search path, and in the context of the specified ClassLoader, which is @@ -209,6 +213,11 @@ public class NativeLibrary implements DynamicLookupHelper { return dynLink.lookupSymbol(libraryHandle, funcName); } + /** Looks up the given function name in all loaded libraries. */ + public static long dynamicLookupFunctionGlobal(String funcName) { + return dynLink.lookupSymbolGlobal(funcName); + } + /** Retrieves the low-level library handle from this NativeLibrary object. On the Windows platform this is an HMODULE, and on Unix and Mac OS X platforms the void* result of calling dlopen(). */ -- cgit v1.2.3 From 555091d37a9a44fb7c35479ddecfee358a559e90 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Thu, 10 Jun 2010 06:13:06 +0200 Subject: 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' --- .../com/jogamp/common/jvm/JNILibLoaderBase.java | 89 +++--- .../com/jogamp/common/os/DynamicLibraryBundle.java | 327 +++++++++++++++++++++ .../jogamp/common/os/DynamicLibraryBundleInfo.java | 75 +++++ src/java/com/jogamp/common/os/NativeLibrary.java | 6 +- .../jogamp/common/os/WindowsDynamicLinkerImpl.java | 2 +- src/java/com/jogamp/common/util/MiscUtils.java | 57 ++++ .../jogamp/gluegen/runtime/ProcAddressTable.java | 7 +- 7 files changed, 522 insertions(+), 41 deletions(-) create mode 100755 src/java/com/jogamp/common/os/DynamicLibraryBundle.java create mode 100644 src/java/com/jogamp/common/os/DynamicLibraryBundleInfo.java create mode 100644 src/java/com/jogamp/common/util/MiscUtils.java (limited to 'src/java/com/jogamp/common/os/NativeLibrary.java') 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.
+ * The implementation should ignore, if the library has been loaded already.
+ * @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.
+ * Optionally preloads the libraries specified by preload.
+ * The implementation should ignore, if any library has been loaded already.
* @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 + *
    + *
  • The to-be-glued native library, eg OpenGL32.dll. From hereon this is referred as the Tool.
  • + *
  • The JNI glue-code native library, eg jogl_desktop.dll. From heron this is referred as the Glue
  • + *

+ * 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}.
+ * 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
GetProcAddress
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/*>*/ toolLibNames; + private boolean[] toolLibLoaded; + private int toolLibLoadedNumber; + protected List/**/ nativeLibraries; + + private List/**/ 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/**/ 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*/ 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.
+ *
    + *
  • GL/GLU example Unix: [ [ "libGL.so.1", "libGL.so", "GL" ], [ "libGLU.so", "GLU" ] ]
  • + *
  • GL/GLU example Windows: [ "OpenGL32", "GLU32" ]
  • + *
  • Cg/CgGL example: [ [ "libCg.so", "Cg" ], [ "libCgGL.so", "CgGL" ] ]
  • + * + */ + public List getToolLibNames(); + + /** @return a list of Glue library names.
    + *
      + *
    • GL: [ "nativewindow_x11", "jogl_gl2es12", "jogl_desktop" ]
    • + *
    • NEWT: [ "nativewindow_x11", "newt" ]
    • + *
    • Cg: [ "nativewindow_x11", "jogl_cg" ]
    • + *

    + * Only the last entry is crucial, ie all other are optional preload dependencies and may generate errors, + * which are ignored. + */ + public List/**/ getGlueLibNames(); + + /** May return the native libraries
    GetProcAddressFunc
    names, the first found function is being used.
    + * This could be eg:
     glXGetProcAddressARB, glXGetProcAddressARB 
    .
    + * If your Tool does not has this facility, just return null. + */ + public List getToolGetProcAddressFuncNameList() ; + + /** May implement the lookup function using the Tools facility.
    + * The actual function pointer is provided to allow proper bootstrapping of the ProcAddressTable.
    + */ + 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(); -- cgit v1.2.3