30import java.io.IOException;
31import java.net.URISyntaxException;
32import java.security.PrivilegedAction;
33import java.util.ArrayList;
34import java.util.Arrays;
35import java.util.HashSet;
36import java.util.Iterator;
38import java.util.StringTokenizer;
40import org.jau.io.IOUtil;
41import org.jau.lang.ReflectionUtil;
42import org.jau.sec.SecurityUtil;
48 public static final boolean DEBUG;
49 protected static final boolean PERF;
51 private static final String[] prefixes;
52 private static final String[] suffixes;
53 private static final boolean isOSX;
54 private static String sys_env_lib_path_varname;
56 private static final String tjc_name =
"org.jau.pkg.cache.TempJarCache";
57 private static final ReflectionUtil.MethodAccessor tjcIsInit;
58 private static final ReflectionUtil.MethodAccessor tjcFindLib;
59 private static final boolean tjcAvail;
68 prefixes =
new String[] {
"" };
69 suffixes =
new String[] {
".dll" };
70 sys_env_lib_path_varname =
"PATH";
76 prefixes =
new String[] {
"lib" };
77 suffixes =
new String[] {
".dylib" };
78 sys_env_lib_path_varname =
"DYLD_LIBRARY_PATH";
90 prefixes =
new String[] {
"lib" };
91 suffixes =
new String[] {
".so" };
92 sys_env_lib_path_varname =
"LD_LIBRARY_PATH";
100 }
catch (
final Throwable t) {}
104 tjcAvail = tjcIsInit.
available() && tjcFindLib.available();
106 System.err.println(
"JNILibrary: Available <"+tjc_name+
">, fully avail "+tjcAvail+
" (a "+tjcIsInit.available()+
", b "+tjcFindLib.available()+
")");
113 System.err.println(
"JNILibrary: Not available <"+tjc_name+
">");
118 protected static final Object
perfSync =
new Object();
122 private static final HashSet<String> loaded =
new HashSet<String>();
139 public String run() {
143 final List<String> res =
new ArrayList<String>();
144 if(
null != paths && paths.length() > 0 ) {
145 final StringTokenizer st =
new StringTokenizer(paths, File.pathSeparator);
146 while (st.hasMoreTokens()) {
147 res.add(st.nextToken());
153 public static synchronized boolean isLoaded(
final String libName) {
154 return loaded.contains(libName);
157 private static synchronized void addLoaded(
final String libName) {
160 System.err.println(
"JNILibrary: Loaded Native Library: "+libName);
172 public static synchronized boolean loadLibrary(
final String libname,
final boolean ignoreError,
final ClassLoader cl)
173 throws SecurityException, UnsatisfiedLinkError
178 loadLibraryImpl(libname, cl);
181 System.err.println(
"JNILibrary: loaded "+libname);
183 }
catch (
final UnsatisfiedLinkError e) {
188 if (!ignoreError && e.getMessage().indexOf(
"already loaded") < 0) {
205 public static synchronized void loadLibrary(
final String libname,
final String[] preload,
final boolean preloadIgnoreError,
final ClassLoader cl)
206 throws SecurityException, UnsatisfiedLinkError
210 for (
int i=0; i<preload.length; i++) {
218 private static void loadLibraryImpl(
final String libraryName,
final ClassLoader cl)
throws SecurityException, UnsatisfiedLinkError {
222 final String libraryPath =
findLibrary(libraryName, cl);
224 System.err.println(
"JNILibrary: loadLibraryImpl("+libraryName+
"), TempJarCache: "+libraryPath);
226 if(
null != libraryPath) {
228 System.err.println(
"JNILibrary: System.load("+libraryPath+
") - mode 2");
230 System.load(libraryPath);
234 System.err.println(
"JNILibrary: System.loadLibrary("+libraryName+
") - mode 3: SystemEnvLibraryPaths: "+
getSystemEnvLibraryPaths());
237 System.loadLibrary(libraryName);
239 }
catch (
final UnsatisfiedLinkError ex1) {
241 System.err.println(
"ERROR mode 3 - "+ex1.getMessage());
245 for (
final Iterator<String> iter = possiblePaths.iterator(); 0 == mode && iter.hasNext(); ) {
246 final String path = iter.next();
248 System.err.println(
"JNILibrary: System.load("+path+
") - mode 4");
253 }
catch (
final UnsatisfiedLinkError ex2) {
255 System.err.println(
"n/a - "+ex2.getMessage());
257 if(!iter.hasNext()) {
259 throw new UnsatisfiedLinkError(
"Couldn't load library '"+libraryName+
261 ", nor as "+possiblePaths);
268 System.err.println(
"JNILibrary: loadLibraryImpl("+libraryName+
"): OK - mode "+mode);
272 public static final String
findLibrary(
final String libName,
final ClassLoader loader) {
275 final boolean _tjcIsInit = tjcIsInit.callStaticMethod(
true);
277 res = tjcFindLib.callStaticMethod(libName);
279 System.err.println(
"JNILibrary.findLibrary(<"+libName+
">) (TempJarCache): "+res);
296 final String libBaseName;
299 }
catch (
final URISyntaxException uriEx) {
300 throw new IllegalArgumentException(uriEx);
302 final String libBaseNameLC = isLowerCaseAlready ? libBaseName : libBaseName.toLowerCase();
304 for(
int i=0; i < prefixes.length && 0 > prefixIdx; i++) {
305 if ( libBaseNameLC.startsWith( prefixes[i] ) ) {
309 if( 0 <= prefixIdx ) {
310 for(
int i=0; i < suffixes.length; i++) {
311 if ( libBaseNameLC.endsWith( suffixes[i] ) ) {
312 final int s = prefixes[prefixIdx].length();
313 final int e = suffixes[i].length();
314 return libBaseName.substring(s, libBaseName.length()-e);
325 final boolean searchSystemPath,
326 final boolean searchSystemPathFirst,
327 final ClassLoader loader) {
329 searchSystemPath, searchSystemPathFirst,
337 final String unixLibName,
338 final String macOSXLibName,
339 final boolean searchSystemPath,
340 final boolean searchSystemPathFirst,
341 final ClassLoader loader) {
342 final List<String> paths =
new ArrayList<String>();
343 final String libName = selectName(windowsLibName, unixLibName, macOSXLibName);
344 if (libName ==
null) {
346 System.err.println(
"JNILibrary.enumerateLibraryPaths: empty, no libName selected");
351 System.err.println(
"JNILibrary.enumerateLibraryPaths: libName '"+libName+
"'");
355 final File file =
new File(libName);
356 if (file.isAbsolute()) {
359 System.err.println(
"JNILibrary.enumerateLibraryPaths: done, absolute path found '"+libName+
"'");
364 final String[] baseNames = buildNames(libName);
366 System.err.println(
"JNILibrary.enumerateLibraryPaths: baseNames: "+Arrays.toString(baseNames));
369 if( searchSystemPath && searchSystemPathFirst ) {
371 for (
int i = 0; i < baseNames.length; i++) {
373 System.err.println(
"JNILibrary.enumerateLibraryPaths: add.ssp_1st: "+baseNames[i]);
375 paths.add(baseNames[i]);
380 addAbsPaths(
"add.ssp_1st_macos_old",
"/Library/Frameworks/" + libName +
".framework", baseNames, paths);
382 addAbsPaths(
"add.ssp_1st_macos_cur",
"/System/Library/Frameworks/" + libName +
".framework", baseNames, paths);
386 final String clPath =
findLibrary(libName, loader);
387 if (clPath !=
null) {
389 System.err.println(
"JNILibrary.enumerateLibraryPaths: add.clp: "+clPath);
395 final String[] javaLibraryPaths =
398 public String[] run() {
400 final String usrPath = System.getProperty(
"java.library.path");
401 if(
null != usrPath) {
404 final String sysPath;
405 if( searchSystemPath ) {
406 sysPath = System.getProperty(
"sun.boot.library.path");
407 if(
null != sysPath) {
413 final String[] res =
new String[count];
415 if(
null != sysPath && searchSystemPathFirst ) {
418 if(
null != usrPath) {
421 if(
null != sysPath && !searchSystemPathFirst ) {
427 if (
null != javaLibraryPaths ) {
428 for(
int i=0; i < javaLibraryPaths.length; i++ ) {
429 final StringTokenizer tokenizer =
new StringTokenizer(javaLibraryPaths[i], File.pathSeparator);
430 while (tokenizer.hasMoreTokens()) {
431 addRelPaths(
"add.java.library.path", tokenizer.nextToken(), baseNames, paths);
437 final String userDir =
440 public String run() {
441 return System.getProperty(
"user.dir");
444 addAbsPaths(
"add.user.dir.std", userDir, baseNames, paths);
448 addAbsPaths(
"add.user.dir.fat", userDir+File.separator+
"natives"+File.separator+
PlatformProps.
os_and_arch, baseNames, paths);
450 if( searchSystemPath && !searchSystemPathFirst ) {
452 for (
int i = 0; i < baseNames.length; i++) {
454 System.err.println(
"JNILibrary.enumerateLibraryPaths: add.ssp_lst: "+baseNames[i]);
456 paths.add(baseNames[i]);
461 addAbsPaths(
"add.ssp_lst_macos_old",
"/Library/Frameworks/" + libName +
".Framework", baseNames, paths);
463 addAbsPaths(
"add.ssp_lst_macos_cur",
"/System/Library/Frameworks/" + libName +
".Framework", baseNames, paths);
467 System.err.println(
"JNILibrary.enumerateLibraryPaths: done: "+paths.toString());
473 private static final String selectName(
final String windowsLibName,
474 final String unixLibName,
475 final String macOSXLibName) {
478 return windowsLibName;
482 return macOSXLibName;
489 private static final String[] buildNames(
final String libName) {
493 final String libBaseNameLC;
495 libBaseNameLC = IOUtil.getBasename(libName).toLowerCase();
496 }
catch (
final URISyntaxException uriEx) {
497 throw new IllegalArgumentException(uriEx);
501 for(
int i=0; i<prefixes.length && 0 > prefixIdx; i++) {
502 if (libBaseNameLC.startsWith(prefixes[i])) {
506 if( 0 <= prefixIdx ) {
507 for(
int i=0; i<suffixes.length; i++) {
508 if (libBaseNameLC.endsWith(suffixes[i])) {
509 return new String[] { libName };
513 for(
int i=0; i<suffixes.length && 0 > suffixIdx; i++) {
514 suffixIdx = libBaseNameLC.indexOf(suffixes[i]);
517 if (suffixIdx >= 0) {
519 for (
int i = suffixIdx + suffixes[0].length();
520 i < libName.length();
522 final char c = libName.charAt(i);
523 if (!(c ==
'.' || (c >=
'0' && c <=
'9'))) {
529 return new String[] { libName };
534 final String[] res =
new String[prefixes.length * suffixes.length + ( isOSX ? 1 : 0 )];
536 for (
int i = 0; i < prefixes.length; i++) {
537 for (
int j = 0; j < suffixes.length; j++) {
538 res[idx++] = prefixes[i] + libName + suffixes[j];
543 res[idx++] = libName;
548 private static final void addRelPaths(
final String cause,
final String path,
final String[] baseNames,
final List<String> paths) {
549 final String abs_path;
551 final File fpath =
new File(path);
552 abs_path = fpath.getCanonicalPath();
553 }
catch(
final IOException ioe ) {
555 System.err.println(
"JNILibrary.enumerateLibraryPaths: "+cause+
": Exception "+ioe.getMessage()+
", from path "+path);
559 addAbsPaths(cause, abs_path, baseNames, paths);
561 private static final void addAbsPaths(
final String cause,
final String abs_path,
final String[] baseNames,
final List<String> paths) {
562 for (
int j = 0; j < baseNames.length; j++) {
563 final String p = abs_path + File.separator + baseNames[j];
565 System.err.println(
"JNILibrary.enumerateLibraryPaths: "+cause+
": "+p+
", from path "+abs_path);
static String getBasename(String fname)
Returns the basename of the given fname w/o directory part.
Convenient Method access class.
boolean available()
Returns true if method is available, otherwise false.
Utility methods to simplify reflection access.
static final Class<?> getClass(final String clazzName, final boolean initializeClazz, final ClassLoader cl)
Loads and returns the class or null.
static< T > T doPrivileged(final PrivilegedAction< T > o)
Call wrapper for java.security.AccessController#doPrivileged(PrivilegedAction).
Helper routines for logging and debugging.
static final boolean debug(final String subcomponent)
static final void initSingleton()
Ensures static init block has been issues, i.e.
Static JNI Native Libraries handler.
static final Object perfSync
static final String isValidNativeLibraryName(final String libName, final boolean isLowerCaseAlready)
Comparison of prefix and suffix of the given libName's basename is performed case insensitive
static synchronized void loadLibrary(final String libname, final String[] preload, final boolean preloadIgnoreError, final ClassLoader cl)
Loads the library specified by libname.
static final String getSystemEnvLibraryPathVarname()
Returns the system's environment variable name used for the dynamic linker to resolve library locatio...
static final List< String > getSystemEnvLibraryPaths()
Returns a list of system paths, from the getSystemEnvLibraryPathVarname() variable.
static final List< String > enumerateLibraryPaths(final String windowsLibName, final String unixLibName, final String macOSXLibName, final boolean searchSystemPath, final boolean searchSystemPathFirst, final ClassLoader loader)
Given the base library names (no prefixes/suffixes) for the various platforms, enumerate the possible...
static final boolean DEBUG
static final boolean PERF
static synchronized boolean isLoaded(final String libName)
static synchronized boolean loadLibrary(final String libname, final boolean ignoreError, final ClassLoader cl)
Loads the library specified by libname.
static final String findLibrary(final String libName, final ClassLoader loader)
static final List< String > enumerateLibraryPaths(final String libName, final boolean searchSystemPath, final boolean searchSystemPathFirst, final ClassLoader loader)
Given the base library names (no prefixes/suffixes) for the various platforms, enumerate the possible...
Helper routines for accessing properties.
static final boolean isPropertyDefined(final String property, final boolean jnlpAlias)