use local static variable to hold loaded states

This commit is contained in:
Taro L. Saito 2011-08-01 16:53:00 +09:00
parent 875235229c
commit 94d5356ba9

View File

@ -85,6 +85,10 @@ public class SnappyLoader
private static boolean isLoaded = false; private static boolean isLoaded = false;
private static SnappyNativeAPI api = null; private static SnappyNativeAPI api = null;
// preserved for LocalSnappyNativeLoader
private static HashMap<String, Boolean> loadedLibFiles = new HashMap<String, Boolean>();
private static HashMap<String, Boolean> loadedLib = new HashMap<String, Boolean>();
private static ClassLoader getRootClassLoader() { private static ClassLoader getRootClassLoader() {
ClassLoader cl = SnappyLoader.class.getClassLoader(); ClassLoader cl = SnappyLoader.class.getClassLoader();
while (cl.getParent() != null) { while (cl.getParent() != null) {
@ -158,8 +162,6 @@ public class SnappyLoader
boolean useNativeCodeInjection = !Boolean.parseBoolean(System.getProperty(KEY_SNAPPY_DISABLE_NATIVE_INJECTION, boolean useNativeCodeInjection = !Boolean.parseBoolean(System.getProperty(KEY_SNAPPY_DISABLE_NATIVE_INJECTION,
"false")); "false"));
// Use parent class loader to load SnappyNative, since Tomcat, which uses different class loaders for each webapps, cannot load JNI interface twice
if (useNativeCodeInjection) { if (useNativeCodeInjection) {
try { try {
Class< ? > c = Class.forName(nativeLoaderClassName); Class< ? > c = Class.forName(nativeLoaderClassName);
@ -177,7 +179,9 @@ public class SnappyLoader
} }
} }
// Prepare SnappyNativeLoader or LocalSnappyNativeLoader
Class< ? > nativeLoader = prepareNativeLoader(); Class< ? > nativeLoader = prepareNativeLoader();
// Load the code
loadNativeLibrary(nativeLoader); loadNativeLibrary(nativeLoader);
return api; return api;
} }
@ -191,6 +195,7 @@ public class SnappyLoader
return LocalSnappyNativeLoader.class; return LocalSnappyNativeLoader.class;
} }
else { else {
// Use parent class loader to load SnappyNative, since Tomcat, which uses different class loaders for each webapps, cannot load JNI interface twice
try { try {
final String nativeLoaderClassName = "org.xerial.snappy.SnappyNativeLoader"; final String nativeLoaderClassName = "org.xerial.snappy.SnappyNativeLoader";
ClassLoader rootClassLoader = getRootClassLoader(); ClassLoader rootClassLoader = getRootClassLoader();
@ -239,8 +244,10 @@ public class SnappyLoader
} }
private static void loadNativeLibrary(Class< ? > loaderClass) { private static void loadNativeLibrary(Class< ? > loaderClass) {
if (loaderClass == null)
throw new SnappyError(SnappyErrorCode.FAILED_TO_LOAD_NATIVE_LIBRARY, "missing snappy loader class");
try { try {
if (loaderClass != null) {
File nativeLib = findNativeLibrary(); File nativeLib = findNativeLibrary();
if (nativeLib != null) { if (nativeLib != null) {
// Load extracted or specified snappyjava native library. // Load extracted or specified snappyjava native library.
@ -255,7 +262,6 @@ public class SnappyLoader
isLoaded = true; isLoaded = true;
api = (SnappyNativeAPI) Class.forName("org.xerial.snappy.SnappyNative").newInstance(); api = (SnappyNativeAPI) Class.forName("org.xerial.snappy.SnappyNative").newInstance();
} }
}
catch (Exception e) { catch (Exception e) {
e.printStackTrace(System.err); e.printStackTrace(System.err);
throw new SnappyError(SnappyErrorCode.FAILED_TO_LOAD_NATIVE_LIBRARY, e.getMessage()); throw new SnappyError(SnappyErrorCode.FAILED_TO_LOAD_NATIVE_LIBRARY, e.getMessage());
@ -265,8 +271,6 @@ public class SnappyLoader
private static class LocalSnappyNativeLoader private static class LocalSnappyNativeLoader
{ {
private static HashMap<String, Boolean> loadedLibFiles = new HashMap<String, Boolean>();
private static HashMap<String, Boolean> loadedLib = new HashMap<String, Boolean>();
public static synchronized void load(String lib) { public static synchronized void load(String lib) {
if (loadedLibFiles.containsKey(lib) && loadedLibFiles.get(lib) == true) if (loadedLibFiles.containsKey(lib) && loadedLibFiles.get(lib) == true)