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. 121
      java/src/main/java/org/rocksdb/RocksDB.java

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

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

Loading…
Cancel
Save