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}. * {@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,26 +42,42 @@ 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) {
// loading possibly necessary libraries. return;
for (CompressionType compressionType : CompressionType.values()) { }
try {
if (compressionType.getLibraryName() != null) { if (libraryLoaded.compareAndSet(LibraryState.NOT_LOADED,
System.loadLibrary(compressionType.getLibraryName()); 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
{ while (libraryLoaded.get() == LibraryState.LOADING) {
NativeLibraryLoader.getInstance().loadLibrary(tmpDir); try {
} Thread.sleep(10);
catch (IOException e) } catch(final InterruptedException e) {
{ //ignore
throw new RuntimeException("Unable to load the RocksDB shared library" }
+ e);
} }
} }
@ -60,36 +88,55 @@ 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) {
if (compressionType.equals(CompressionType.NO_COMPRESSION)) { return;
continue; }
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 { try {
System.load(path + "/" + Environment.getSharedLibraryFileName( System.load(path + "/" +
compressionType.getLibraryName())); Environment.getJniLibraryFileName("rocksdbjni"));
success = true;
break; break;
} catch (UnsatisfiedLinkError e) { } 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; while (libraryLoaded.get() == LibraryState.LOADING) {
for (String path : paths) {
try { try {
System.load(path + "/" + Thread.sleep(10);
Environment.getJniLibraryFileName("rocksdbjni")); } catch(final InterruptedException e) {
success = true; //ignore
break;
} catch (UnsatisfiedLinkError e) {
err = e;
} }
} }
if (!success) {
throw err;
}
} }
/** /**

Loading…
Cancel
Save