From c3915abbae3b99686b24a900fa51a2816e8648ba Mon Sep 17 00:00:00 2001 From: Adam Retter Date: Sat, 15 Nov 2014 19:54:44 +0000 Subject: [PATCH 1/2] Minor tidyup and use Java 7 for file copying --- java/org/rocksdb/NativeLibraryLoader.java | 47 ++++++++++------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/java/org/rocksdb/NativeLibraryLoader.java b/java/org/rocksdb/NativeLibraryLoader.java index bf0196e77..73170ba68 100644 --- a/java/org/rocksdb/NativeLibraryLoader.java +++ b/java/org/rocksdb/NativeLibraryLoader.java @@ -1,6 +1,9 @@ package org.rocksdb; import java.io.*; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; + import org.rocksdb.util.Environment; /** @@ -8,42 +11,32 @@ import org.rocksdb.util.Environment; * The shared library is extracted to a temp folder and loaded from there. */ public class NativeLibraryLoader { - private static String sharedLibraryName = Environment.getJniLibraryName("rocksdb"); - private static String tempFileSuffix = "." + Environment.getJniLibraryExtension(); + private static final String sharedLibraryName = Environment.getJniLibraryName("rocksdb"); + private static final String tempFilePrefix = "librocksdbjni"; + private static final String tempFileSuffix = "." + Environment.getJniLibraryExtension(); - public static void loadLibraryFromJar(String tmpDir) + public static void loadLibraryFromJar(final String tmpDir) throws IOException { - File temp; - String tempFilePrefix = "librocksdbjni"; - if(tmpDir == null || tmpDir.equals("")) + final File temp; + if(tmpDir == null || tmpDir.equals("")) { temp = File.createTempFile(tempFilePrefix, tempFileSuffix); - else - temp = new File(tmpDir + "/" + sharedLibraryName); - - temp.deleteOnExit(); + } else { + temp = new File(tmpDir, sharedLibraryName); + } if (!temp.exists()) { throw new RuntimeException("File " + temp.getAbsolutePath() + " does not exist."); + } else { + temp.deleteOnExit(); } - byte[] buffer = new byte[102400]; - int readBytes; - - InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(sharedLibraryName); - if (is == null) { - throw new RuntimeException(sharedLibraryName + " was not found inside JAR."); - } - - OutputStream os = null; - try { - os = new FileOutputStream(temp); - while ((readBytes = is.read(buffer)) != -1) { - os.write(buffer, 0, readBytes); + // attempt to copy the library from the JAR to the temp destination + try(final InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(sharedLibraryName)) { + if (is == null) { + throw new RuntimeException(sharedLibraryName + " was not found inside JAR."); + } else { + Files.copy(is, temp.toPath(), StandardCopyOption.REPLACE_EXISTING); } - } finally { - if(os != null) - os.close(); - is.close(); } System.load(temp.getAbsolutePath()); From 585c759cf382945102d0f0f7fb70dc33612d9970 Mon Sep 17 00:00:00 2001 From: Adam Retter Date: Sat, 15 Nov 2014 23:41:01 +0000 Subject: [PATCH 2/2] Make sure to use the correct Java classloader for loading the RocksDB Native Library --- java/org/rocksdb/NativeLibraryLoader.java | 30 ++++++++++++++++++++--- java/org/rocksdb/RocksDB.java | 2 +- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/java/org/rocksdb/NativeLibraryLoader.java b/java/org/rocksdb/NativeLibraryLoader.java index 73170ba68..32836f670 100644 --- a/java/org/rocksdb/NativeLibraryLoader.java +++ b/java/org/rocksdb/NativeLibraryLoader.java @@ -11,11 +11,35 @@ import org.rocksdb.util.Environment; * The shared library is extracted to a temp folder and loaded from there. */ public class NativeLibraryLoader { + //singleton + private static final NativeLibraryLoader instance = new NativeLibraryLoader(); + private static final String sharedLibraryName = Environment.getJniLibraryName("rocksdb"); private static final String tempFilePrefix = "librocksdbjni"; private static final String tempFileSuffix = "." + Environment.getJniLibraryExtension(); - public static void loadLibraryFromJar(final String tmpDir) + /** + * Get a reference to the NativeLibraryLoader + * + * @return The NativeLibraryLoader + */ + public static NativeLibraryLoader getInstance() { + return instance; + } + + /** + * Attempts to extract the native RocksDB library + * from the classpath and load it + * + * @param tmpDir A temporary directory to use + * to copy the native library to. If null, + * or the empty string, we rely on Java's + * {@see java.io.File#createTempFile(String, String) } + * function to provide a temporary location. + * The temporary file will be registered for deletion + * on exit. + */ + public void loadLibraryFromJar(final String tmpDir) throws IOException { final File temp; if(tmpDir == null || tmpDir.equals("")) { @@ -30,8 +54,8 @@ public class NativeLibraryLoader { temp.deleteOnExit(); } - // attempt to copy the library from the JAR to the temp destination - try(final InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(sharedLibraryName)) { + // attempt to copy the library from the Jar file to the temp destination + try(final InputStream is = getClass().getClassLoader().getResourceAsStream(sharedLibraryName)) { if (is == null) { throw new RuntimeException(sharedLibraryName + " was not found inside JAR."); } else { diff --git a/java/org/rocksdb/RocksDB.java b/java/org/rocksdb/RocksDB.java index 5fcfd2ff4..79b00f3c0 100644 --- a/java/org/rocksdb/RocksDB.java +++ b/java/org/rocksdb/RocksDB.java @@ -44,7 +44,7 @@ public class RocksDB extends RocksObject { } try { - NativeLibraryLoader.loadLibraryFromJar(tmpDir); + NativeLibraryLoader.getInstance().loadLibraryFromJar(tmpDir); } catch (IOException e) {