Minor fixes to RocksJava Native Library initialization (#1287)

* [bugfix] Make sure the Native Library is initialized. Closes https://github.com/facebook/rocksdb/issues/989

* [bugfix] Just load the native libraries once
main
Adam Retter 8 years ago committed by Yueh-Hsuan Chiang
parent 48e4e842b7
commit 48fd619a47
  1. 3
      java/src/main/java/org/rocksdb/FlushOptions.java
  2. 71
      java/src/main/java/org/rocksdb/RocksDB.java

@ -5,6 +5,9 @@ package org.rocksdb;
* {@link org.rocksdb.RocksDB}. * {@link org.rocksdb.RocksDB}.
*/ */
public class FlushOptions extends RocksObject { public class FlushOptions extends RocksObject {
static {
RocksDB.loadLibrary();
}
/** /**
* Construct a new instance of FlushOptions. * Construct a new instance of FlushOptions.

@ -7,6 +7,9 @@ package org.rocksdb;
import java.util.*; import java.util.*;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.rocksdb.util.Environment; import org.rocksdb.util.Environment;
/** /**
@ -19,6 +22,15 @@ public class RocksDB extends RocksObject {
public static final byte[] DEFAULT_COLUMN_FAMILY = "default".getBytes(); public static final byte[] DEFAULT_COLUMN_FAMILY = "default".getBytes();
public static final int NOT_FOUND = -1; public static final int NOT_FOUND = -1;
private enum LibraryState {
NOT_LOADED,
LOADING,
LOADED
}
private static AtomicReference<LibraryState> libraryLoaded
= new AtomicReference<>(LibraryState.NOT_LOADED);
static { static {
RocksDB.loadLibrary(); RocksDB.loadLibrary();
} }
@ -30,10 +42,16 @@ public class RocksDB extends RocksObject {
* java.io.tmpdir, however, you can override this temporary location by * java.io.tmpdir, however, you can override this temporary location by
* setting the environment variable ROCKSDB_SHAREDLIB_DIR. * setting the environment variable ROCKSDB_SHAREDLIB_DIR.
*/ */
public static synchronized void loadLibrary() { public static void loadLibrary() {
String tmpDir = System.getenv("ROCKSDB_SHAREDLIB_DIR"); if (libraryLoaded.get() == LibraryState.LOADED) {
return;
}
if (libraryLoaded.compareAndSet(LibraryState.NOT_LOADED,
LibraryState.LOADING)) {
final String tmpDir = System.getenv("ROCKSDB_SHAREDLIB_DIR");
// loading possibly necessary libraries. // loading possibly necessary libraries.
for (CompressionType compressionType : CompressionType.values()) { for (final CompressionType compressionType : CompressionType.values()) {
try { try {
if (compressionType.getLibraryName() != null) { if (compressionType.getLibraryName() != null) {
System.loadLibrary(compressionType.getLibraryName()); System.loadLibrary(compressionType.getLibraryName());
@ -42,15 +60,25 @@ public class RocksDB extends RocksObject {
// since it may be optional, we ignore its loading failure here. // since it may be optional, we ignore its loading failure here.
} }
} }
try try {
{
NativeLibraryLoader.getInstance().loadLibrary(tmpDir); NativeLibraryLoader.getInstance().loadLibrary(tmpDir);
} } catch (IOException e) {
catch (IOException e) libraryLoaded.set(LibraryState.NOT_LOADED);
{
throw new RuntimeException("Unable to load the RocksDB shared library" throw new RuntimeException("Unable to load the RocksDB shared library"
+ e); + e);
} }
libraryLoaded.set(LibraryState.LOADED);
return;
}
while (libraryLoaded.get() == LibraryState.LOADING) {
try {
Thread.sleep(10);
} catch(final InterruptedException e) {
//ignore
}
}
} }
/** /**
@ -60,12 +88,18 @@ public class RocksDB extends RocksObject {
* @param paths a list of strings where each describes a directory * @param paths a list of strings where each describes a directory
* of a library. * of a library.
*/ */
public static synchronized void loadLibrary(final List<String> paths) { public static void loadLibrary(final List<String> paths) {
for (CompressionType compressionType : CompressionType.values()) { if (libraryLoaded.get() == LibraryState.LOADED) {
return;
}
if (libraryLoaded.compareAndSet(LibraryState.NOT_LOADED,
LibraryState.LOADING)) {
for (final CompressionType compressionType : CompressionType.values()) {
if (compressionType.equals(CompressionType.NO_COMPRESSION)) { if (compressionType.equals(CompressionType.NO_COMPRESSION)) {
continue; continue;
} }
for (String path : paths) { for (final String path : paths) {
try { try {
System.load(path + "/" + Environment.getSharedLibraryFileName( System.load(path + "/" + Environment.getSharedLibraryFileName(
compressionType.getLibraryName())); compressionType.getLibraryName()));
@ -77,7 +111,7 @@ public class RocksDB extends RocksObject {
} }
boolean success = false; boolean success = false;
UnsatisfiedLinkError err = null; UnsatisfiedLinkError err = null;
for (String path : paths) { for (final String path : paths) {
try { try {
System.load(path + "/" + System.load(path + "/" +
Environment.getJniLibraryFileName("rocksdbjni")); Environment.getJniLibraryFileName("rocksdbjni"));
@ -88,8 +122,21 @@ public class RocksDB extends RocksObject {
} }
} }
if (!success) { if (!success) {
libraryLoaded.set(LibraryState.NOT_LOADED);
throw err; throw err;
} }
libraryLoaded.set(LibraryState.LOADED);
return;
}
while (libraryLoaded.get() == LibraryState.LOADING) {
try {
Thread.sleep(10);
} catch(final InterruptedException e) {
//ignore
}
}
} }
/** /**

Loading…
Cancel
Save