Skip to content

Commit

Permalink
fix NativeLibLoader on Java 9+ (#315)
Browse files Browse the repository at this point in the history
Co-authored-by: Zhaochen Guo <zhaochen@diffbot.com>
  • Loading branch information
guozhaochen and Zhaochen Guo authored Sep 20, 2021
1 parent 80a7410 commit 936a085
Showing 1 changed file with 7 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ public class NativeLibLoader {
private static final Log logger = LogFactory.getLog(NativeLibLoader.class);

private static boolean initialized = false;
private static final String nativePath = "../lib/";
private static final String nativeResourcePath = "/lib/";
private static final String[] libNames = new String[]{"treelite4j"};

Expand All @@ -30,7 +29,13 @@ public class NativeLibLoader {
static synchronized void initTreeliteRuntime() throws IOException {
if (!initialized) {
for (String libName : libNames) {
smartLoad(libName);
try {
String libraryFromJar = nativeResourcePath + System.mapLibraryName(libName);
loadLibraryFromJar(libraryFromJar);
} catch (IOException ioe) {
logger.error("failed to load " + libName + " library from jar");
throw ioe;
}
}
initialized = true;
}
Expand Down Expand Up @@ -125,55 +130,4 @@ public static String createTempFileFromResource(String path) throws
}
return temp.getAbsolutePath();
}

/**
* load native library, this method will first try to load library from java.library.path, then
* try to load library in jar package.
*
* @param libName library path
* @throws IOException exception
*/
private static void smartLoad(String libName) throws IOException {
addNativeDir(nativePath);
try {
System.loadLibrary(libName);
} catch (UnsatisfiedLinkError e) {
try {
String libraryFromJar = nativeResourcePath + System.mapLibraryName(libName);
loadLibraryFromJar(libraryFromJar);
} catch (IOException ioe) {
logger.error("failed to load library from both native path and jar");
throw ioe;
}
}
}

/**
* Add libPath to java.library.path, then native library in libPath would be load properly
*
* @param libPath library path
* @throws IOException exception
*/
private static void addNativeDir(String libPath) throws IOException {
try {
Field field = ClassLoader.class.getDeclaredField("usr_paths");
field.setAccessible(true);
String[] paths = (String[]) field.get(null);
for (String path : paths) {
if (libPath.equals(path)) {
return;
}
}
String[] tmp = new String[paths.length + 1];
System.arraycopy(paths, 0, tmp, 0, paths.length);
tmp[paths.length] = libPath;
field.set(null, tmp);
} catch (IllegalAccessException e) {
logger.error(e.getMessage());
throw new IOException("Failed to get permissions to set library path");
} catch (NoSuchFieldException e) {
logger.error(e.getMessage());
throw new IOException("Failed to get field handle to set library path");
}
}
}

0 comments on commit 936a085

Please sign in to comment.