From a3ab998ef942e82d06c0b4b775b4d1b5d2a808dc Mon Sep 17 00:00:00 2001 From: Yueh-Hsuan Chiang Date: Wed, 30 Apr 2014 11:54:02 -0700 Subject: [PATCH] [Java] Add static method RocksDB.loadLibrary() Summary: Add static method RocksDB.loadLibrary() which loads necessary library files. Test Plan: make rocksdbjava make jtest make jdb_bench java/jdb_bench.sh Reviewers: haobo, dhruba, sdong, ankgup87, rsumbaly, swapnilghike, zzbennett Reviewed By: ankgup87 CC: leveldb Differential Revision: https://reviews.facebook.net/D18375 --- java/Makefile | 2 +- java/RocksDBSample.java | 2 +- java/org/rocksdb/RocksDB.java | 55 +++++++++++++++++++++ java/org/rocksdb/WriteBatchTest.java | 2 +- java/org/rocksdb/benchmark/DbBenchmark.java | 2 +- java/org/rocksdb/test/BackupableDBTest.java | 2 +- java/org/rocksdb/test/OptionsTest.java | 3 +- java/org/rocksdb/test/ReadOptionsTest.java | 5 +- java/org/rocksdb/util/Environment.java | 37 ++++++++++++++ 9 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 java/org/rocksdb/util/Environment.java diff --git a/java/Makefile b/java/Makefile index 1a199e1df..9d21b5750 100644 --- a/java/Makefile +++ b/java/Makefile @@ -8,7 +8,7 @@ clean: rm -f $(ROCKSDB_JAR) java: - javac org/rocksdb/*.java org/rocksdb/util/*.java + javac org/rocksdb/util/*.java org/rocksdb/*.java jar -cf $(ROCKSDB_JAR) org/rocksdb/*.class org/rocksdb/util/*.class javah -d $(NATIVE_INCLUDE) -jni $(NATIVE_JAVA_CLASSES) diff --git a/java/RocksDBSample.java b/java/RocksDBSample.java index 2e27e9377..2d9e3a920 100644 --- a/java/RocksDBSample.java +++ b/java/RocksDBSample.java @@ -13,7 +13,7 @@ import java.io.IOException; public class RocksDBSample { static { - System.loadLibrary("rocksdbjni"); + RocksDB.loadLibrary(); } public static void main(String[] args) { diff --git a/java/org/rocksdb/RocksDB.java b/java/org/rocksdb/RocksDB.java index 9ff45707f..4d2c89d4b 100644 --- a/java/org/rocksdb/RocksDB.java +++ b/java/org/rocksdb/RocksDB.java @@ -10,6 +10,7 @@ import java.util.Map; import java.util.HashMap; import java.io.Closeable; import java.io.IOException; +import org.rocksdb.util.Environment; /** * A RocksDB is a persistent ordered map from keys to values. It is safe for @@ -19,6 +20,60 @@ import java.io.IOException; */ public class RocksDB { public static final int NOT_FOUND = -1; + private static final String[] compressionLibs_ = { + "snappy", "zlib", "bzip2", "lz4", "lz4hc"}; + + /** + * Loads the necessary library files. + * Calling this method twice will have no effect. + */ + public static synchronized void loadLibrary() { + // loading possibly necessary libraries. + for (String lib : compressionLibs_) { + try { + System.loadLibrary(lib); + } catch (UnsatisfiedLinkError e) { + // since it may be optional, we ignore its loading failure here. + } + } + // However, if any of them is required. We will see error here. + System.loadLibrary("rocksdbjni"); + } + + /** + * Tries to load the necessary library files from the given list of + * directories. + * + * @param paths a list of strings where each describes a directory + * of a library. + */ + public static synchronized void loadLibrary(List paths) { + for (String lib : compressionLibs_) { + for (String path : paths) { + try { + System.load(path + "/" + Environment.getSharedLibraryName(lib)); + break; + } catch (UnsatisfiedLinkError e) { + // since they are optional, we ignore loading fails. + } + } + } + boolean success = false; + UnsatisfiedLinkError err = null; + for (String path : paths) { + try { + System.load(path + "/" + Environment.getJniLibraryName("rocksdbjni")); + success = true; + break; + } catch (UnsatisfiedLinkError e) { + err = e; + } + } + if (success == false) { + throw err; + } + } + /** * The factory constructor of RocksDB that opens a RocksDB instance given * the path to the database using the default options w/ createIfMissing diff --git a/java/org/rocksdb/WriteBatchTest.java b/java/org/rocksdb/WriteBatchTest.java index e54f94675..03a866313 100644 --- a/java/org/rocksdb/WriteBatchTest.java +++ b/java/org/rocksdb/WriteBatchTest.java @@ -16,7 +16,7 @@ import java.io.UnsupportedEncodingException; */ public class WriteBatchTest { static { - System.loadLibrary("rocksdbjni"); + RocksDB.loadLibrary(); } public static void main(String args[]) { diff --git a/java/org/rocksdb/benchmark/DbBenchmark.java b/java/org/rocksdb/benchmark/DbBenchmark.java index 84ee34bf1..5404b726a 100644 --- a/java/org/rocksdb/benchmark/DbBenchmark.java +++ b/java/org/rocksdb/benchmark/DbBenchmark.java @@ -172,7 +172,7 @@ public class DbBenchmark { } static { - System.loadLibrary("rocksdbjni"); + RocksDB.loadLibrary(); } abstract class BenchmarkTask implements Callable { diff --git a/java/org/rocksdb/test/BackupableDBTest.java b/java/org/rocksdb/test/BackupableDBTest.java index 8af51dd16..f0fc3d501 100644 --- a/java/org/rocksdb/test/BackupableDBTest.java +++ b/java/org/rocksdb/test/BackupableDBTest.java @@ -11,7 +11,7 @@ public class BackupableDBTest { static final String db_path = "/tmp/backupablejni_db"; static final String backup_path = "/tmp/backupablejni_db_backup"; static { - System.loadLibrary("rocksdbjni"); + RocksDB.loadLibrary(); } public static void main(String[] args) { diff --git a/java/org/rocksdb/test/OptionsTest.java b/java/org/rocksdb/test/OptionsTest.java index cd3ba785d..e1e0e059e 100644 --- a/java/org/rocksdb/test/OptionsTest.java +++ b/java/org/rocksdb/test/OptionsTest.java @@ -6,11 +6,12 @@ package org.rocksdb.test; import java.util.Random; +import org.rocksdb.RocksDB; import org.rocksdb.Options; public class OptionsTest { static { - System.loadLibrary("rocksdbjni"); + RocksDB.loadLibrary(); } public static void main(String[] args) { Options opt = new Options(); diff --git a/java/org/rocksdb/test/ReadOptionsTest.java b/java/org/rocksdb/test/ReadOptionsTest.java index 501eda6cf..b3b5b2690 100644 --- a/java/org/rocksdb/test/ReadOptionsTest.java +++ b/java/org/rocksdb/test/ReadOptionsTest.java @@ -6,11 +6,12 @@ package org.rocksdb.test; import java.util.Random; -import org.rocksdb.*; +import org.rocksdb.RocksDB; +import org.rocksdb.ReadOptions; public class ReadOptionsTest { static { - System.loadLibrary("rocksdbjni"); + RocksDB.loadLibrary(); } public static void main(String[] args) { ReadOptions opt = new ReadOptions(); diff --git a/java/org/rocksdb/util/Environment.java b/java/org/rocksdb/util/Environment.java new file mode 100644 index 000000000..c2e3bc088 --- /dev/null +++ b/java/org/rocksdb/util/Environment.java @@ -0,0 +1,37 @@ +package org.rocksdb.util; + +public class Environment { + private static String OS = System.getProperty("os.name").toLowerCase(); + + public static boolean isWindows() { + return (OS.indexOf("win") >= 0); + } + + public static boolean isMac() { + return (OS.indexOf("mac") >= 0); + } + + public static boolean isUnix() { + return (OS.indexOf("nix") >= 0 || + OS.indexOf("nux") >= 0 || + OS.indexOf("aix") >= 0); + } + + public static String getSharedLibraryName(String name) { + if (isUnix()) { + return String.format("lib%s.so", name); + } else if (isMac()) { + return String.format("lib%s.dylib", name); + } + throw new UnsupportedOperationException(); + } + + public static String getJniLibraryName(String name) { + if (isUnix()) { + return String.format("lib%s.so", name); + } else if (isMac()) { + return String.format("lib%s.jnilib", name); + } + throw new UnsupportedOperationException(); + } +}