mirror of
https://github.com/xerial/snappy-java.git
synced 2025-07-27 16:04:16 +02:00
Applied a patch from Alec Wysoker for finding snappy DLL via java.library.path
This commit is contained in:
parent
6771e58b46
commit
85d9cc9084
@ -1,244 +1,244 @@
|
|||||||
/*--------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------
|
||||||
* Copyright 2011 Taro L. Saito
|
* Copyright 2011 Taro L. Saito
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
//--------------------------------------
|
//--------------------------------------
|
||||||
// snappy-java Project
|
// snappy-java Project
|
||||||
//
|
//
|
||||||
// LoadSnappy.java
|
// LoadSnappy.java
|
||||||
// Since: 2011/03/29
|
// Since: 2011/03/29
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Author$
|
// $Author$
|
||||||
//--------------------------------------
|
//--------------------------------------
|
||||||
package org.xerial.snappy;
|
package org.xerial.snappy;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.security.DigestInputStream;
|
import java.security.DigestInputStream;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class loads a native library of Snappy according to the platform of the
|
* This class loads a native library of Snappy according to the platform of the
|
||||||
* user.
|
* user.
|
||||||
*
|
*
|
||||||
* @author leo
|
* @author leo
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class LoadSnappy
|
public class LoadSnappy
|
||||||
{
|
{
|
||||||
private static boolean isLoaded = false;
|
private static boolean isLoaded = false;
|
||||||
|
|
||||||
public static boolean load() {
|
public static boolean load() {
|
||||||
if (!isLoaded) {
|
if (!isLoaded) {
|
||||||
loadSnappyNativeLibrary();
|
loadSnappyNativeLibrary();
|
||||||
}
|
}
|
||||||
return isLoaded;
|
return isLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the MD5 value of the input stream
|
* Computes the MD5 value of the input stream
|
||||||
*
|
*
|
||||||
* @param input
|
* @param input
|
||||||
* @return
|
* @return
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException
|
||||||
*/
|
*/
|
||||||
static String md5sum(InputStream input) throws IOException {
|
static String md5sum(InputStream input) throws IOException {
|
||||||
BufferedInputStream in = new BufferedInputStream(input);
|
BufferedInputStream in = new BufferedInputStream(input);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
|
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
|
||||||
DigestInputStream digestInputStream = new DigestInputStream(in, digest);
|
DigestInputStream digestInputStream = new DigestInputStream(in, digest);
|
||||||
for (; digestInputStream.read() >= 0;) {
|
for (; digestInputStream.read() >= 0;) {
|
||||||
|
|
||||||
}
|
}
|
||||||
ByteArrayOutputStream md5out = new ByteArrayOutputStream();
|
ByteArrayOutputStream md5out = new ByteArrayOutputStream();
|
||||||
md5out.write(digest.digest());
|
md5out.write(digest.digest());
|
||||||
return md5out.toString();
|
return md5out.toString();
|
||||||
}
|
}
|
||||||
catch (NoSuchAlgorithmException e) {
|
catch (NoSuchAlgorithmException e) {
|
||||||
throw new IllegalStateException("MD5 algorithm is not available: " + e);
|
throw new IllegalStateException("MD5 algorithm is not available: " + e);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
in.close();
|
in.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the specified library file to the target folder
|
* Extract the specified library file to the target folder
|
||||||
*
|
*
|
||||||
* @param libFolderForCurrentOS
|
* @param libFolderForCurrentOS
|
||||||
* @param libraryFileName
|
* @param libraryFileName
|
||||||
* @param targetFolder
|
* @param targetFolder
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private static boolean extractAndLoadLibraryFile(String libFolderForCurrentOS, String libraryFileName,
|
private static boolean extractAndLoadLibraryFile(String libFolderForCurrentOS, String libraryFileName,
|
||||||
String targetFolder) {
|
String targetFolder) {
|
||||||
String nativeLibraryFilePath = libFolderForCurrentOS + "/" + libraryFileName;
|
String nativeLibraryFilePath = libFolderForCurrentOS + "/" + libraryFileName;
|
||||||
final String prefix = "snappy-" + getVersion() + "-";
|
final String prefix = "snappy-" + getVersion() + "-";
|
||||||
|
|
||||||
String extractedLibFileName = prefix + libraryFileName;
|
String extractedLibFileName = prefix + libraryFileName;
|
||||||
File extractedLibFile = new File(targetFolder, extractedLibFileName);
|
File extractedLibFile = new File(targetFolder, extractedLibFileName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (extractedLibFile.exists()) {
|
if (extractedLibFile.exists()) {
|
||||||
// test md5sum value
|
// test md5sum value
|
||||||
String md5sum1 = md5sum(LoadSnappy.class.getResourceAsStream(nativeLibraryFilePath));
|
String md5sum1 = md5sum(LoadSnappy.class.getResourceAsStream(nativeLibraryFilePath));
|
||||||
String md5sum2 = md5sum(new FileInputStream(extractedLibFile));
|
String md5sum2 = md5sum(new FileInputStream(extractedLibFile));
|
||||||
|
|
||||||
if (md5sum1.equals(md5sum2)) {
|
if (md5sum1.equals(md5sum2)) {
|
||||||
return loadNativeLibrary(targetFolder, extractedLibFileName);
|
return loadNativeLibrary(targetFolder, extractedLibFileName);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// remove old native library file
|
// remove old native library file
|
||||||
boolean deletionSucceeded = extractedLibFile.delete();
|
boolean deletionSucceeded = extractedLibFile.delete();
|
||||||
if (!deletionSucceeded) {
|
if (!deletionSucceeded) {
|
||||||
throw new IOException("failed to remove existing native library file: "
|
throw new IOException("failed to remove existing native library file: "
|
||||||
+ extractedLibFile.getAbsolutePath());
|
+ extractedLibFile.getAbsolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract file into the current directory
|
// extract file into the current directory
|
||||||
InputStream reader = LoadSnappy.class.getResourceAsStream(nativeLibraryFilePath);
|
InputStream reader = LoadSnappy.class.getResourceAsStream(nativeLibraryFilePath);
|
||||||
FileOutputStream writer = new FileOutputStream(extractedLibFile);
|
FileOutputStream writer = new FileOutputStream(extractedLibFile);
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
int bytesRead = 0;
|
int bytesRead = 0;
|
||||||
while ((bytesRead = reader.read(buffer)) != -1) {
|
while ((bytesRead = reader.read(buffer)) != -1) {
|
||||||
writer.write(buffer, 0, bytesRead);
|
writer.write(buffer, 0, bytesRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.close();
|
writer.close();
|
||||||
reader.close();
|
reader.close();
|
||||||
|
|
||||||
if (!System.getProperty("os.name").contains("Windows")) {
|
if (!System.getProperty("os.name").contains("Windows")) {
|
||||||
try {
|
try {
|
||||||
Runtime.getRuntime().exec(new String[] { "chmod", "755", extractedLibFile.getAbsolutePath() })
|
Runtime.getRuntime().exec(new String[] { "chmod", "755", extractedLibFile.getAbsolutePath() })
|
||||||
.waitFor();
|
.waitFor();
|
||||||
}
|
}
|
||||||
catch (Throwable e) {}
|
catch (Throwable e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
return loadNativeLibrary(targetFolder, extractedLibFileName);
|
return loadNativeLibrary(targetFolder, extractedLibFileName);
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
System.err.println(e.getMessage());
|
System.err.println(e.getMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static synchronized boolean loadNativeLibrary(String path, String name) {
|
private static synchronized boolean loadNativeLibrary(String path, String name) {
|
||||||
File libPath = new File(path, name);
|
File libPath = new File(path, name);
|
||||||
if (libPath.exists()) {
|
if (libPath.exists()) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
System.load(new File(path, name).getAbsolutePath());
|
System.load(new File(path, name).getAbsolutePath());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (UnsatisfiedLinkError e) {
|
catch (UnsatisfiedLinkError e) {
|
||||||
throw new SnappyError(SnappyErrorCode.FAILED_TO_LOAD_NATIVE_LIBRARY, e);
|
throw new SnappyError(SnappyErrorCode.FAILED_TO_LOAD_NATIVE_LIBRARY, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadSnappyNativeLibrary() {
|
private static void loadSnappyNativeLibrary() {
|
||||||
if (isLoaded)
|
if (isLoaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Try loading the library from org.xerial.snappy.lib.path library path */
|
// Try loading the library from org.xerial.snappy.lib.path library path */
|
||||||
String snappyNativeLibraryPath = System.getProperty("org.xerial.snappy.lib.path");
|
String snappyNativeLibraryPath = System.getProperty("org.xerial.snappy.lib.path");
|
||||||
String snappyNativeLibraryName = System.getProperty("org.xerial.snappy.lib.name");
|
String snappyNativeLibraryName = System.getProperty("org.xerial.snappy.lib.name");
|
||||||
|
|
||||||
// Resolve the library file name with a suffix (e.g., dll, .so, etc.)
|
// Resolve the library file name with a suffix (e.g., dll, .so, etc.)
|
||||||
if (snappyNativeLibraryName == null)
|
if (snappyNativeLibraryName == null)
|
||||||
snappyNativeLibraryName = System.mapLibraryName("snappy");
|
snappyNativeLibraryName = System.mapLibraryName("snappy");
|
||||||
|
|
||||||
if (snappyNativeLibraryPath != null) {
|
if (snappyNativeLibraryPath != null) {
|
||||||
if (loadNativeLibrary(snappyNativeLibraryPath, snappyNativeLibraryName)) {
|
if (loadNativeLibrary(snappyNativeLibraryPath, snappyNativeLibraryName)) {
|
||||||
isLoaded = true;
|
isLoaded = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the os-dependent library from a jar file
|
// Load the os-dependent library from a jar file
|
||||||
snappyNativeLibraryPath = "/org/xerial/snappy/native/" + OSInfo.getNativeLibFolderPathForCurrentOS();
|
snappyNativeLibraryPath = "/org/xerial/snappy/native/" + OSInfo.getNativeLibFolderPathForCurrentOS();
|
||||||
|
|
||||||
if (LoadSnappy.class.getResource(snappyNativeLibraryPath + "/" + snappyNativeLibraryName) == null) {
|
if (LoadSnappy.class.getResource(snappyNativeLibraryPath + "/" + snappyNativeLibraryName) != null) {
|
||||||
// use nested VM version
|
// Temporary library folder. Use the value of java.io.tmpdir
|
||||||
return;
|
String tempFolder = new File(System.getProperty("java.io.tmpdir")).getAbsolutePath();
|
||||||
}
|
// Try extracting the library from jar
|
||||||
|
if (extractAndLoadLibraryFile(snappyNativeLibraryPath, snappyNativeLibraryName, tempFolder)) {
|
||||||
// Temporary library folder. Use the value of java.io.tmpdir
|
return;
|
||||||
String tempFolder = new File(System.getProperty("java.io.tmpdir")).getAbsolutePath();
|
}
|
||||||
// Try extracting the library from jar
|
}
|
||||||
if (extractAndLoadLibraryFile(snappyNativeLibraryPath, snappyNativeLibraryName, tempFolder)) {
|
try {
|
||||||
isLoaded = true;
|
System.loadLibrary("snappy");
|
||||||
return;
|
isLoaded = true;
|
||||||
}
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
isLoaded = false;
|
||||||
isLoaded = false;
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void getNativeLibraryFolderForTheCurrentOS() {
|
private static void getNativeLibraryFolderForTheCurrentOS() {
|
||||||
String osName = OSInfo.getOSName();
|
String osName = OSInfo.getOSName();
|
||||||
String archName = OSInfo.getArchName();
|
String archName = OSInfo.getArchName();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getMajorVersion() {
|
public static int getMajorVersion() {
|
||||||
String[] c = getVersion().split("\\.");
|
String[] c = getVersion().split("\\.");
|
||||||
return (c.length > 0) ? Integer.parseInt(c[0]) : 1;
|
return (c.length > 0) ? Integer.parseInt(c[0]) : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getMinorVersion() {
|
public static int getMinorVersion() {
|
||||||
String[] c = getVersion().split("\\.");
|
String[] c = getVersion().split("\\.");
|
||||||
return (c.length > 1) ? Integer.parseInt(c[1]) : 0;
|
return (c.length > 1) ? Integer.parseInt(c[1]) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getVersion() {
|
public static String getVersion() {
|
||||||
|
|
||||||
URL versionFile = LoadSnappy.class.getResource("/META-INF/maven/org.xerial.snappy/snappy-java/pom.properties");
|
URL versionFile = LoadSnappy.class.getResource("/META-INF/maven/org.xerial.snappy/snappy-java/pom.properties");
|
||||||
if (versionFile == null)
|
if (versionFile == null)
|
||||||
versionFile = LoadSnappy.class.getResource("/META-INF/maven/org.xerial.snappy/snappy-java/VERSION");
|
versionFile = LoadSnappy.class.getResource("/META-INF/maven/org.xerial.snappy/snappy-java/VERSION");
|
||||||
|
|
||||||
String version = "unknown";
|
String version = "unknown";
|
||||||
try {
|
try {
|
||||||
if (versionFile != null) {
|
if (versionFile != null) {
|
||||||
Properties versionData = new Properties();
|
Properties versionData = new Properties();
|
||||||
versionData.load(versionFile.openStream());
|
versionData.load(versionFile.openStream());
|
||||||
version = versionData.getProperty("version", version);
|
version = versionData.getProperty("version", version);
|
||||||
version = version.trim().replaceAll("[^0-9\\.]", "");
|
version = version.trim().replaceAll("[^0-9\\.]", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
System.err.println(e);
|
System.err.println(e);
|
||||||
}
|
}
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user