From 9db13987b1095fddbc18c328b163332ed295dda9 Mon Sep 17 00:00:00 2001 From: Chris Riccomini Date: Fri, 26 Sep 2014 13:57:12 -0700 Subject: [PATCH] Update RocksDB's Java bindings to support multiple native RocksDB builds in the same Jar file. Cross build RocksDB for linux32 and linux64 using Vagrant. Build a cross-platform fat jar that contains osx, linux32, and linux64 RocksDB static builds. --- Makefile | 14 ++++++++++--- java/Makefile | 8 ++++++-- java/crossbuild/README.md | 0 java/crossbuild/Vagrantfile | 25 +++++++++++++++++++++++ java/crossbuild/build-linux.sh | 11 ++++++++++ java/org/rocksdb/NativeLibraryLoader.java | 6 +++--- java/org/rocksdb/util/Environment.java | 14 +++++++++++-- 7 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 java/crossbuild/README.md create mode 100644 java/crossbuild/Vagrantfile create mode 100755 java/crossbuild/build-linux.sh diff --git a/Makefile b/Makefile index 9d626e17f..9fc1fe6de 100644 --- a/Makefile +++ b/Makefile @@ -270,6 +270,7 @@ clean: -rm -rf ios-x86/* ios-arm/* -find . -name "*.[oda]" -exec rm {} \; -find . -type f -regex ".*\.\(\(gcda\)\|\(gcno\)\)" -exec rm {} \; + -rm -rf bzip2* snappy* zlib* tags: ctags * -R cscope -b `find . -name '*.cc'` `find . -name '*.h'` @@ -510,11 +511,14 @@ ldb: tools/ldb.o $(LIBOBJECTS) JNI_NATIVE_SOURCES = ./java/rocksjni/*.cc JAVA_INCLUDE = -I$(JAVA_HOME)/include/ -I$(JAVA_HOME)/include/linux -ROCKSDBJNILIB = librocksdbjni.so -ROCKSDB_JAR = rocksdbjni.jar +ARCH := $(shell getconf LONG_BIT) +ROCKSDBJNILIB = librocksdbjni-linux$(ARCH).so +ROCKSDB_JAR = rocksdbjni-linux$(ARCH).jar +ROCKSDB_JAR_ALL = rocksdbjni-all.jar ifeq ($(PLATFORM), OS_MACOSX) -ROCKSDBJNILIB = librocksdbjni.jnilib +ROCKSDBJNILIB = librocksdbjni-osx.jnilib +ROCKSDB_JAR = rocksdbjni-osx.jar JAVA_INCLUDE = -I/System/Library/Frameworks/JavaVM.framework/Headers/ endif @@ -549,6 +553,10 @@ rocksdbjavastatic: libz.a libbz2.a libsnappy.a cd java;jar -cf $(ROCKSDB_JAR) org/rocksdb/*.class org/rocksdb/util/*.class HISTORY*.md $(ROCKSDBJNILIB) +rocksdbjavastaticrelease: rocksdbjavastatic + cd java/crossbuild && vagrant destroy -f && vagrant up + cd java;jar -cf $(ROCKSDB_JAR_ALL) org/rocksdb/*.class org/rocksdb/util/*.class HISTORY*.md librocksdbjni-*.so librocksdbjni-*.jnilib + rocksdbjava: OPT="-fPIC -DNDEBUG -O2" $(MAKE) $(LIBRARY) -j32 cd java;$(MAKE) java; diff --git a/java/Makefile b/java/Makefile index b2f3674f0..1b854755b 100644 --- a/java/Makefile +++ b/java/Makefile @@ -1,12 +1,16 @@ NATIVE_JAVA_CLASSES = org.rocksdb.RocksDB org.rocksdb.Options org.rocksdb.WriteBatch org.rocksdb.WriteBatchInternal org.rocksdb.WriteBatchTest org.rocksdb.WriteOptions org.rocksdb.BackupableDB org.rocksdb.BackupableDBOptions org.rocksdb.Statistics org.rocksdb.RocksIterator org.rocksdb.VectorMemTableConfig org.rocksdb.SkipListMemTableConfig org.rocksdb.HashLinkedListMemTableConfig org.rocksdb.HashSkipListMemTableConfig org.rocksdb.PlainTableConfig org.rocksdb.BlockBasedTableConfig org.rocksdb.ReadOptions org.rocksdb.Filter org.rocksdb.BloomFilter org.rocksdb.RestoreOptions org.rocksdb.RestoreBackupableDB org.rocksdb.RocksEnv org.rocksdb.GenericRateLimiterConfig NATIVE_INCLUDE = ./include -ROCKSDB_JAR = rocksdbjni.jar +ARCH := $(shell getconf LONG_BIT) +ROCKSDB_JAR = rocksdbjni-linux$(ARCH).jar + +ifeq ($(PLATFORM), OS_MACOSX) +ROCKSDB_JAR = rocksdbjni-osx.jar +endif clean: -find . -name "*.class" -exec rm {} \; -find . -name "hs*.log" -exec rm {} \; - rm -f $(ROCKSDB_JAR) java: javac org/rocksdb/util/*.java org/rocksdb/*.java diff --git a/java/crossbuild/README.md b/java/crossbuild/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/java/crossbuild/Vagrantfile b/java/crossbuild/Vagrantfile new file mode 100644 index 000000000..47e76b7da --- /dev/null +++ b/java/crossbuild/Vagrantfile @@ -0,0 +1,25 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + + config.vm.define "linux32" do |linux32| + linux32.vm.box = "ubuntu/trusty32" + linux32.vm.provision :shell, path: "build-linux.sh" + linux32.vm.synced_folder "../..", "/rocksdb" + end + + config.vm.define "linux64" do |linux64| + linux64.vm.box = "ubuntu/trusty64" + linux64.vm.provision :shell, path: "build-linux.sh" + linux64.vm.synced_folder "../..", "/rocksdb" + end + + config.vm.provider "virtualbox" do |v| + v.memory = 2048 + v.cpus = 4 + end +end diff --git a/java/crossbuild/build-linux.sh b/java/crossbuild/build-linux.sh new file mode 100755 index 000000000..37b808140 --- /dev/null +++ b/java/crossbuild/build-linux.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# install all required packages for rocksdb +sudo apt-get update +sudo apt-get -y install git make gcc g++ libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev default-jdk + +# set java home so we can build rocksdb jars +export JAVA_HOME=$(echo /usr/lib/jvm/java-7-openjdk*) +cd /rocksdb +make jclean clean -j 4 rocksdbjavastatic +sudo shutdown -h now + diff --git a/java/org/rocksdb/NativeLibraryLoader.java b/java/org/rocksdb/NativeLibraryLoader.java index 440056582..367c4dc5b 100644 --- a/java/org/rocksdb/NativeLibraryLoader.java +++ b/java/org/rocksdb/NativeLibraryLoader.java @@ -1,16 +1,16 @@ package org.rocksdb; import java.io.*; - +import org.rocksdb.util.Environment; /** * This class is used to load the RocksDB shared library from within the jar. * The shared library is extracted to a temp folder and loaded from there. */ public class NativeLibraryLoader { - private static String sharedLibraryName = "librocksdbjni.so"; + private static String sharedLibraryName = Environment.getJniLibraryName("rockdsb"); private static String tempFilePrefix = "librocksdbjni"; - private static String tempFileSuffix = ".so"; + private static String tempFileSuffix = "." + Environment.getJniLibraryExtension(); public static void loadLibraryFromJar(String tmpDir) throws IOException { diff --git a/java/org/rocksdb/util/Environment.java b/java/org/rocksdb/util/Environment.java index c2e3bc088..1158908a2 100644 --- a/java/org/rocksdb/util/Environment.java +++ b/java/org/rocksdb/util/Environment.java @@ -2,6 +2,7 @@ package org.rocksdb.util; public class Environment { private static String OS = System.getProperty("os.name").toLowerCase(); + private static String ARCH = System.getProperty("os.arch").toLowerCase(); public static boolean isWindows() { return (OS.indexOf("win") >= 0); @@ -17,6 +18,10 @@ public class Environment { OS.indexOf("aix") >= 0); } + public static boolean is64Bit() { + return (ARCH.indexOf("64") > 0); + } + public static String getSharedLibraryName(String name) { if (isUnix()) { return String.format("lib%s.so", name); @@ -28,10 +33,15 @@ public class Environment { public static String getJniLibraryName(String name) { if (isUnix()) { - return String.format("lib%s.so", name); + String arch = (is64Bit()) ? "64" : "32"; + return String.format("lib%s-linux%s.so", name, arch); } else if (isMac()) { - return String.format("lib%s.jnilib", name); + return String.format("lib%s-osx.jnilib", name); } throw new UnsupportedOperationException(); } + + public static String getJniLibraryExtension() { + return (isMac()) ? ".jnilib" : ".so"; + } }