diff options
Diffstat (limited to 'src/java')
7 files changed, 169 insertions, 60 deletions
diff --git a/src/java/com/jogamp/common/os/DynamicLibraryBundle.java b/src/java/com/jogamp/common/os/DynamicLibraryBundle.java index fee3c01..a513ec4 100644 --- a/src/java/com/jogamp/common/os/DynamicLibraryBundle.java +++ b/src/java/com/jogamp/common/os/DynamicLibraryBundle.java @@ -1,5 +1,5 @@ /** - * Copyright 2010 JogAmp Community. All rights reserved. + * Copyright 2010-2023 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -61,11 +61,12 @@ import com.jogamp.common.util.RunnableExecutor; public class DynamicLibraryBundle implements DynamicLookupHelper { private final DynamicLibraryBundleInfo info; - protected final List<NativeLibrary> nativeLibraries; - private final DynamicLinker dynLinkGlobal; private final List<List<String>> toolLibNames; + protected final List<NativeLibrary> toolLibraries; + private final List<String> toolLibSymbolNames; private final List<String> glueLibNames; private final boolean[] toolLibLoaded; + private final DynamicLinker dynLinkGlobal; private int toolLibLoadedNumber; @@ -97,8 +98,9 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { if(DEBUG) { System.err.println(Thread.currentThread().getName()+" - DynamicLibraryBundle.init start with: "+info.getClass().getName()); } - nativeLibraries = new ArrayList<NativeLibrary>(); toolLibNames = info.getToolLibNames(); + toolLibraries = new ArrayList<NativeLibrary>(toolLibNames.size()); + toolLibSymbolNames = info.getSymbolForToolLibPath(); glueLibNames = info.getGlueLibNames(); toolLibLoaded = new boolean[toolLibNames.size()]; if(DEBUG) { @@ -143,7 +145,9 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { System.err.println("DynamicLibraryBundle.init Summary: "+info.getClass().getName()); System.err.println(" toolGetProcAddressFuncNameList: "+toolGetProcAddressFuncNameList+", complete: "+toolGetProcAddressComplete+", 0x"+Long.toHexString(toolGetProcAddressHandle)); System.err.println(" Tool Lib Names : "+toolLibNames); + System.err.println(" Tool Lib Symbol: "+toolLibSymbolNames); System.err.println(" Tool Lib Loaded: "+getToolLibLoadedNumber()+"/"+getToolLibNumber()+" "+Arrays.toString(toolLibLoaded)+", complete "+isToolLibComplete()); + System.err.println(" Tool Libraries : "+toolLibraries); System.err.println(" Glue Lib Names : "+glueLibNames); System.err.println(" Glue Lib Loaded: "+getGlueLibLoadedNumber()+"/"+getGlueLibNumber()+" "+Arrays.toString(glueLibLoaded)+", complete "+isGlueLibComplete()); System.err.println(" All Complete: "+isLibComplete()); @@ -159,10 +163,13 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { toolGetProcAddressFuncNameSet = null; toolGetProcAddressHandle = 0; toolGetProcAddressComplete = false; - for(int i = 0; i<nativeLibraries.size(); i++) { - nativeLibraries.get(i).close(); + for(int i = 0; i<toolLibraries.size(); i++) { + final NativeLibrary lib = toolLibraries.get(i); + if( null != lib ) { + lib.close(); + } } - nativeLibraries.clear(); + toolLibraries.clear(); toolLibNames.clear(); glueLibNames.clear(); if(DEBUG) { @@ -206,6 +213,12 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { return false; } + /** + * Returns list of {@link NativeLibrary}s for each {@link DynamicLibraryBundleInfo#getToolLibNames()} in the same size and order. + * May contain elements with {@code null} for not loaded libs. + */ + public final List<NativeLibrary> getToolLibraries() { return toolLibraries; } + public final int getGlueLibNumber() { return glueLibNames.size(); } @@ -252,9 +265,9 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { protected static final NativeLibrary loadFirstAvailable(final List<String> libNames, final boolean searchSystemPath, final boolean searchSystemPathFirst, - final ClassLoader loader, final boolean global) throws SecurityException { + final ClassLoader loader, final boolean global, final String symbolName) throws SecurityException { for (int i=0; i < libNames.size(); i++) { - final NativeLibrary lib = NativeLibrary.open(libNames.get(i), searchSystemPath, searchSystemPathFirst, loader, global); + final NativeLibrary lib = NativeLibrary.open(libNames.get(i), searchSystemPath, searchSystemPathFirst, loader, global, symbolName); if (lib != null) { return lib; } @@ -271,11 +284,13 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { for (i=0; i < toolLibNames.size(); i++) { final List<String> libNames = toolLibNames.get(i); + final String symbolName = toolLibSymbolNames.get(i); if( null != libNames && libNames.size() > 0 ) { lib = loadFirstAvailable(libNames, info.searchToolLibInSystemPath(), info.searchToolLibSystemPathFirst(), - cl, info.shallLinkGlobal()); + cl, info.shallLinkGlobal(), symbolName); + toolLibraries.add(lib); if ( null == lib ) { if(DEBUG) { System.err.println("Unable to load any Tool library of: "+libNames); @@ -284,13 +299,14 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { if( null == dynLinkGlobal ) { dynLinkGlobal = lib.dynamicLinker(); } - nativeLibraries.add(lib); - toolLibLoaded[i]=true; + toolLibLoaded[i] = true; toolLibLoadedNumber++; if(DEBUG) { System.err.println("Loaded Tool library: "+lib); } } + } else { + toolLibraries.add(null); // same size and order as toolLibNames! } } if( toolLibNames.size() > 0 && !isToolLibLoaded() ) { @@ -347,16 +363,19 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { addr = dynLinkGlobal.lookupSymbolGlobal(funcName); } // Look up this function name in all known libraries - for (int i=0; 0==addr && i < nativeLibraries.size(); i++) { - lib = nativeLibraries.get(i); - addr = lib.dynamicLookupFunction(funcName); + for (int i=0; 0==addr && i < toolLibraries.size(); i++) { + final NativeLibrary lib0 = toolLibraries.get(i); + if( null != lib0 ) { + lib = lib0; + addr = lib0.dynamicLookupFunction(funcName); + } } if(DEBUG_LOOKUP) { final 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 " + nativeLibraries); + System.err.println("Lookup-Native: <" + funcName + "> ** FAILED ** in libs " + toolLibraries); } } return addr; @@ -377,14 +396,20 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { @Override public final void claimAllLinkPermission() throws SecurityException { - for (int i=0; i < nativeLibraries.size(); i++) { - nativeLibraries.get(i).claimAllLinkPermission(); + for(int i = 0; i<toolLibraries.size(); i++) { + final NativeLibrary lib = toolLibraries.get(i); + if( null != lib ) { + lib.claimAllLinkPermission(); + } } } @Override public final void releaseAllLinkPermission() throws SecurityException { - for (int i=0; i < nativeLibraries.size(); i++) { - nativeLibraries.get(i).releaseAllLinkPermission(); + for(int i = 0; i<toolLibraries.size(); i++) { + final NativeLibrary lib = toolLibraries.get(i); + if( null != lib ) { + lib.releaseAllLinkPermission(); + } } } diff --git a/src/java/com/jogamp/common/os/DynamicLibraryBundleInfo.java b/src/java/com/jogamp/common/os/DynamicLibraryBundleInfo.java index 01068b4..0d9f1f8 100644 --- a/src/java/com/jogamp/common/os/DynamicLibraryBundleInfo.java +++ b/src/java/com/jogamp/common/os/DynamicLibraryBundleInfo.java @@ -1,5 +1,5 @@ /** - * Copyright 2010 JogAmp Community. All rights reserved. + * Copyright 2010-2023 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -65,6 +65,11 @@ public interface DynamicLibraryBundleInfo { public List<List<String>> getToolLibNames(); /** + * Returns optional list of optional symbol names per {@link #getToolLibNames()} in same order for an OS which requires the symbol's address to retrieve the path of the containing library. + */ + public List<String> getSymbolForToolLibPath(); + + /** * If a {@link SecurityManager} is installed, user needs link permissions * for the named libraries. * diff --git a/src/java/com/jogamp/common/os/DynamicLinker.java b/src/java/com/jogamp/common/os/DynamicLinker.java index 4019c77..7b12aee 100644 --- a/src/java/com/jogamp/common/os/DynamicLinker.java +++ b/src/java/com/jogamp/common/os/DynamicLinker.java @@ -1,5 +1,5 @@ /** - * Copyright 2013 JogAmp Community. All rights reserved. + * Copyright 2013-2023 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -72,6 +72,19 @@ public interface DynamicLinker { public long openLibraryLocal(String pathname, boolean debug) throws SecurityException; /** + * Security checks are implicit by previous call of + * {@link #openLibraryLocal(String, boolean)} or {@link #openLibraryGlobal(String, boolean)} + * retrieving the <code>librarHandle</code>. + * + * @param libraryHandle a library handle previously retrieved via {@link #openLibraryLocal(String, boolean)} or {@link #openLibraryGlobal(String, boolean)}. + * @param symbolName optional symbol name for an OS which requires the symbol's address to retrieve the path of the containing library + * @return the library pathname if found and supported by OS or {@code null}. + * @throws IllegalArgumentException in case case <code>libraryHandle</code> is unknown. + * @throws SecurityException if user is not granted access for the given library handle + */ + public String lookupLibraryPathname(long libraryHandle, String symbolName) throws SecurityException; + + /** * If a {@link SecurityManager} is installed, user needs link permissions * for <b>all</b> libraries, i.e. for <code>new RuntimePermission("loadLibrary.*");</code>! * diff --git a/src/java/com/jogamp/common/os/NativeLibrary.java b/src/java/com/jogamp/common/os/NativeLibrary.java index 53db784..e00599c 100644 --- a/src/java/com/jogamp/common/os/NativeLibrary.java +++ b/src/java/com/jogamp/common/os/NativeLibrary.java @@ -1,41 +1,30 @@ -/* - * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2011 JogAmp Community. All rights reserved. +/** + * Copyright 2011-2023 JogAmp Community. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. * - * - Redistribution 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. + * 2. 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 Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR + * CONTRIBUTORS 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. * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - * Sun gratefully acknowledges that this software was originally authored - * and developed by Kenneth Bradley Russell and Christopher John Kline. + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. */ package com.jogamp.common.os; @@ -126,13 +115,17 @@ public final class NativeLibrary implements DynamicLookupHelper { // May as well keep around the path to the library we opened private final String libraryPath; + // Native library path of the opened native libraryHandle, maybe null + private final String nativeLibraryPath; + private final boolean global; // Private constructor to prevent arbitrary instances from floating around - private NativeLibrary(final DynamicLinker dynLink, final long libraryHandle, final String libraryPath, final boolean global) { + private NativeLibrary(final DynamicLinker dynLink, final long libraryHandle, final String libraryPath, final boolean global, final String symbolName) { this.dynLink = dynLink; this.libraryHandle = libraryHandle; this.libraryPath = libraryPath; + this.nativeLibraryPath = dynLink.lookupLibraryPathname(libraryHandle, symbolName); this.global = global; if (DEBUG) { System.err.println("NativeLibrary.open(): Successfully loaded: " + this); @@ -141,7 +134,9 @@ public final class NativeLibrary implements DynamicLookupHelper { @Override public final String toString() { - return "NativeLibrary[" + dynLink.getClass().getSimpleName() + ", " + libraryPath + ", 0x" + Long.toHexString(libraryHandle) + ", global " + global + "]"; + final String nlp_s = null != nativeLibraryPath ? ", native '"+nativeLibraryPath+"'" : ""; + return "NativeLibrary[" + dynLink.getClass().getSimpleName() + ", path[given '" + libraryPath + "'"+nlp_s+"], 0x" + + Long.toHexString(libraryHandle) + ", global " + global + "]"; } /** @@ -198,7 +193,36 @@ public final class NativeLibrary implements DynamicLookupHelper { final boolean searchSystemPath, final boolean searchSystemPathFirst, final ClassLoader loader, final boolean global) throws SecurityException { - return open(libName, libName, libName, searchSystemPath, searchSystemPathFirst, loader, global); + return open(libName, libName, libName, searchSystemPath, searchSystemPathFirst, loader, global, null); + } + + /** Opens the given native library, assuming it has the same base + name on all platforms. + <p> + The {@code searchSystemPath} argument changes the behavior to + either use the default system path or not at all. + </p> + <p> + Assuming {@code searchSystemPath} is {@code true}, + the {@code searchSystemPathFirst} argument changes the behavior to first + search the default system path rather than searching it last. + </p> + * @param libName library name, with or without prefix and suffix + * @param searchSystemPath if {@code true} library shall be searched in the system path <i>(default)</i>, otherwise {@code false}. + * @param searchSystemPathFirst if {@code true} system path shall be searched <i>first</i> <i>(default)</i>, rather than searching it last. + * if {@code searchSystemPath} is {@code false} this argument is ignored. + * @param loader {@link ClassLoader} to locate the library + * @param global if {@code true} allows system wide access of the loaded library, otherwise access is restricted to the process. + * @param symbolName optional symbol name for an OS which requires the symbol's address to retrieve the path of the containing library + * @return {@link NativeLibrary} instance or {@code null} if library could not be loaded. + * @throws SecurityException if user is not granted access for the named library. + * @since 2.4.0 + */ + public static final NativeLibrary open(final String libName, + final boolean searchSystemPath, + final boolean searchSystemPathFirst, + final ClassLoader loader, final boolean global, final String symbolName) throws SecurityException { + return open(libName, libName, libName, searchSystemPath, searchSystemPathFirst, loader, global, symbolName); } /** Opens the given native library, assuming it has the given base @@ -230,6 +254,7 @@ public final class NativeLibrary implements DynamicLookupHelper { * if {@code searchSystemPath} is {@code false} this argument is ignored. * @param loader {@link ClassLoader} to locate the library * @param global if {@code true} allows system wide access of the loaded library, otherwise access is restricted to the process. + * @param symbolName optional symbol name for an OS which requires the symbol's address to retrieve the path of the containing library * @return {@link NativeLibrary} instance or {@code null} if library could not be loaded. * @throws SecurityException if user is not granted access for the named library. */ @@ -238,7 +263,7 @@ public final class NativeLibrary implements DynamicLookupHelper { final String macOSXLibName, final boolean searchSystemPath, final boolean searchSystemPathFirst, - final ClassLoader loader, final boolean global) throws SecurityException { + final ClassLoader loader, final boolean global, final String symbolName) throws SecurityException { final List<String> possiblePaths = enumerateLibraryPaths(windowsLibName, unixLibName, macOSXLibName, @@ -267,7 +292,7 @@ public final class NativeLibrary implements DynamicLookupHelper { res = 0; } if ( 0 != res ) { - return new NativeLibrary(dynLink, res, path, global); + return new NativeLibrary(dynLink, res, path, global, symbolName); } else if( DEBUG ) { if( null != t ) { System.err.println("NativeLibrary.open: Caught "+t.getClass().getSimpleName()+": "+t.getMessage()); @@ -366,6 +391,11 @@ public final class NativeLibrary implements DynamicLookupHelper { return libraryPath; } + /** Returns the native library path of the opened native {@link #getLibraryHandle()}, maybe null if not supported by OS. */ + public final String getNativeLibraryPath() { + return nativeLibraryPath; + } + /** Closes this native library. Further lookup operations are not allowed after calling this method. * @throws SecurityException if user is not granted access for the named library. diff --git a/src/java/jogamp/common/os/DynamicLinkerImpl.java b/src/java/jogamp/common/os/DynamicLinkerImpl.java index 5ce94c1..13b08d7 100644 --- a/src/java/jogamp/common/os/DynamicLinkerImpl.java +++ b/src/java/jogamp/common/os/DynamicLinkerImpl.java @@ -45,6 +45,7 @@ import com.jogamp.common.util.SecurityUtil; /** * @throws SecurityException if user is not granted global access */ + @Override public final void claimAllLinkPermission() throws SecurityException { synchronized( secSync ) { allLinkPermissionGranted = true; @@ -54,6 +55,7 @@ import com.jogamp.common.util.SecurityUtil; /** * @throws SecurityException if user is not granted global access */ + @Override public final void releaseAllLinkPermission() throws SecurityException { synchronized( secSync ) { allLinkPermissionGranted = false; @@ -120,6 +122,17 @@ import com.jogamp.common.util.SecurityUtil; protected abstract long openLibraryLocalImpl(final String pathname) throws SecurityException; @Override + public final String lookupLibraryPathname(final long libraryHandle, final String symbolName) throws SecurityException { + checkLinkPermission(libraryHandle); + final String fname = lookupLibraryPathnameImpl(libraryHandle, symbolName); + if(DEBUG_LOOKUP) { + System.err.println("DynamicLinkerImpl.lookupLibraryPathname(0x"+Long.toHexString(libraryHandle)+", "+symbolName+") -> '"+fname+"'"); + } + return fname; + } + protected abstract String lookupLibraryPathnameImpl(final long libraryHandle, String symbolName) throws SecurityException; + + @Override public final long lookupSymbolGlobal(final String symbolName) throws SecurityException { checkAllLinkPermission(); final long addr = lookupSymbolGlobalImpl(symbolName); diff --git a/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java b/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java index ddaeea2..4a0aeb4 100644 --- a/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java +++ b/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java @@ -47,6 +47,20 @@ package jogamp.common.os; /** Interface to C language function: <br> <code> void * dlsym(void * , const char * ); </code> */ protected static native long dlsym(long arg0, java.lang.String arg1); + /** Interface to C language function: <br> <code> int dladdr(void * , Dl_info *); </code>, returning the <code>Dl_info.dli_fname</code> */ + protected static native java.lang.String dladdr_fname(long arg0); + + @Override + protected final String lookupLibraryPathnameImpl(final long libraryHandle, final String symbolName) throws SecurityException { + if( 0 != libraryHandle && null != symbolName && symbolName.length() > 0 ) { + final long addr = dlsym(libraryHandle, symbolName); + if( 0 != addr ) { + return dladdr_fname(addr); + } + } + return null; + } + @Override protected final long lookupSymbolLocalImpl(final long libraryHandle, final String symbolName) throws SecurityException { return 0 != libraryHandle ? dlsym(libraryHandle, symbolName) : 0; diff --git a/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java b/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java index 04f13fb..a99cb35 100644 --- a/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java +++ b/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java @@ -41,6 +41,9 @@ public final class WindowsDynamicLinkerImpl extends DynamicLinkerImpl { /** Interface to C language function: <br> <code> HANDLE LoadLibraryW(LPCWSTR lpLibFileName); </code> */ private static native long LoadLibraryW(java.lang.String lpLibFileName); + /** Interface to C language function: <br> <code> PROC GetModuleFileNameA(HANDLE hModule, LPSTR lpFilename, DWORD nSize); </code> */ + private static native java.lang.String GetModuleFileNameA(long hModule); + @Override protected final long openLibraryLocalImpl(final String libraryName) throws SecurityException { // How does that work under Windows ? @@ -54,6 +57,12 @@ public final class WindowsDynamicLinkerImpl extends DynamicLinkerImpl { } @Override + protected final String lookupLibraryPathnameImpl(final long libraryHandle, final String symbolName) throws SecurityException { + // symbolName is not required + return 0 != libraryHandle ? GetModuleFileNameA(libraryHandle) : null; + } + + @Override protected final long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException { if(DEBUG_LOOKUP) { System.err.println("lookupSymbolGlobal: Not supported on Windows"); |