mirror of
https://github.com/xerial/snappy-java.git
synced 2025-04-08 19:35:08 +02:00
Add native DLL loader
This commit is contained in:
parent
7b52820c44
commit
e09c3d1439
226
src/main/java/org/xerial/snappy/LoadSnappy.java
Executable file
226
src/main/java/org/xerial/snappy/LoadSnappy.java
Executable file
@ -0,0 +1,226 @@
|
||||
//--------------------------------------
|
||||
// snappy-java Project
|
||||
//
|
||||
// LoadSnappy.java
|
||||
// Since: 2011/03/29
|
||||
//
|
||||
// $URL$
|
||||
// $Author$
|
||||
//--------------------------------------
|
||||
package org.xerial.snappy;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author leo
|
||||
*
|
||||
*/
|
||||
public class LoadSnappy
|
||||
{
|
||||
private static boolean extracted = false;
|
||||
|
||||
public static boolean initialize() {
|
||||
if (!extracted)
|
||||
loadSQLiteNativeLibrary();
|
||||
return extracted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the MD5 value of the input stream
|
||||
*
|
||||
* @param input
|
||||
* @return
|
||||
* @throws IOException
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
static String md5sum(InputStream input) throws IOException {
|
||||
BufferedInputStream in = new BufferedInputStream(input);
|
||||
|
||||
try {
|
||||
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
|
||||
DigestInputStream digestInputStream = new DigestInputStream(in, digest);
|
||||
for (; digestInputStream.read() >= 0;) {
|
||||
|
||||
}
|
||||
ByteArrayOutputStream md5out = new ByteArrayOutputStream();
|
||||
md5out.write(digest.digest());
|
||||
return md5out.toString();
|
||||
}
|
||||
catch (NoSuchAlgorithmException e) {
|
||||
throw new IllegalStateException("MD5 algorithm is not available: " + e);
|
||||
}
|
||||
finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the specified library file to the target folder
|
||||
*
|
||||
* @param libFolderForCurrentOS
|
||||
* @param libraryFileName
|
||||
* @param targetFolder
|
||||
* @return
|
||||
*/
|
||||
private static boolean extractAndLoadLibraryFile(String libFolderForCurrentOS, String libraryFileName,
|
||||
String targetFolder) {
|
||||
String nativeLibraryFilePath = libFolderForCurrentOS + "/" + libraryFileName;
|
||||
final String prefix = "sqlite-" + getVersion() + "-";
|
||||
|
||||
String extractedLibFileName = prefix + libraryFileName;
|
||||
File extractedLibFile = new File(targetFolder, extractedLibFileName);
|
||||
|
||||
try {
|
||||
if (extractedLibFile.exists()) {
|
||||
// test md5sum value
|
||||
String md5sum1 = md5sum(LoadSnappy.class.getResourceAsStream(nativeLibraryFilePath));
|
||||
String md5sum2 = md5sum(new FileInputStream(extractedLibFile));
|
||||
|
||||
if (md5sum1.equals(md5sum2)) {
|
||||
return loadNativeLibrary(targetFolder, extractedLibFileName);
|
||||
}
|
||||
else {
|
||||
// remove old native library file
|
||||
boolean deletionSucceeded = extractedLibFile.delete();
|
||||
if (!deletionSucceeded) {
|
||||
throw new IOException("failed to remove existing native library file: "
|
||||
+ extractedLibFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// extract file into the current directory
|
||||
InputStream reader = LoadSnappy.class.getResourceAsStream(nativeLibraryFilePath);
|
||||
FileOutputStream writer = new FileOutputStream(extractedLibFile);
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead = 0;
|
||||
while ((bytesRead = reader.read(buffer)) != -1) {
|
||||
writer.write(buffer, 0, bytesRead);
|
||||
}
|
||||
|
||||
writer.close();
|
||||
reader.close();
|
||||
|
||||
if (!System.getProperty("os.name").contains("Windows")) {
|
||||
try {
|
||||
Runtime.getRuntime().exec(new String[] { "chmod", "755", extractedLibFile.getAbsolutePath() })
|
||||
.waitFor();
|
||||
}
|
||||
catch (Throwable e) {}
|
||||
}
|
||||
|
||||
return loadNativeLibrary(targetFolder, extractedLibFileName);
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static synchronized boolean loadNativeLibrary(String path, String name) {
|
||||
File libPath = new File(path, name);
|
||||
if (libPath.exists()) {
|
||||
|
||||
try {
|
||||
System.load(new File(path, name).getAbsolutePath());
|
||||
return true;
|
||||
}
|
||||
catch (UnsatisfiedLinkError e) {
|
||||
System.err.println(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void loadSQLiteNativeLibrary() {
|
||||
if (extracted)
|
||||
return;
|
||||
|
||||
// Try loading library from org.sqlite.lib.path library path */
|
||||
String sqliteNativeLibraryPath = System.getProperty("org.sqlite.lib.path");
|
||||
String sqliteNativeLibraryName = System.getProperty("org.sqlite.lib.name");
|
||||
if (sqliteNativeLibraryName == null)
|
||||
sqliteNativeLibraryName = System.mapLibraryName("sqlitejdbc");
|
||||
|
||||
if (sqliteNativeLibraryPath != null) {
|
||||
if (loadNativeLibrary(sqliteNativeLibraryPath, sqliteNativeLibraryName)) {
|
||||
extracted = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Load the os-dependent library from a jar file
|
||||
sqliteNativeLibraryPath = "/native/" + OSInfo.getNativeLibFolderPathForCurrentOS();
|
||||
|
||||
if (LoadSnappy.class.getResource(sqliteNativeLibraryPath + "/" + sqliteNativeLibraryName) == null) {
|
||||
// use nested VM version
|
||||
return;
|
||||
}
|
||||
|
||||
// temporary library folder
|
||||
String tempFolder = new File(System.getProperty("java.io.tmpdir")).getAbsolutePath();
|
||||
// Try extracting the library from jar
|
||||
if (extractAndLoadLibraryFile(sqliteNativeLibraryPath, sqliteNativeLibraryName, tempFolder)) {
|
||||
extracted = true;
|
||||
return;
|
||||
}
|
||||
|
||||
extracted = false;
|
||||
return;
|
||||
}
|
||||
|
||||
private static void getNativeLibraryFolderForTheCurrentOS() {
|
||||
String osName = OSInfo.getOSName();
|
||||
String archName = OSInfo.getArchName();
|
||||
|
||||
}
|
||||
|
||||
public static int getMajorVersion() {
|
||||
String[] c = getVersion().split("\\.");
|
||||
return (c.length > 0) ? Integer.parseInt(c[0]) : 1;
|
||||
}
|
||||
|
||||
public static int getMinorVersion() {
|
||||
String[] c = getVersion().split("\\.");
|
||||
return (c.length > 1) ? Integer.parseInt(c[1]) : 0;
|
||||
}
|
||||
|
||||
public static String getVersion() {
|
||||
|
||||
URL versionFile = LoadSnappy.class.getResource("/META-INF/maven/org.xerial/snappy-java/pom.properties");
|
||||
if (versionFile == null)
|
||||
versionFile = LoadSnappy.class.getResource("/META-INF/maven/org.xerial/snappy-java/VERSION");
|
||||
|
||||
String version = "unknown";
|
||||
try {
|
||||
if (versionFile != null) {
|
||||
Properties versionData = new Properties();
|
||||
versionData.load(versionFile.openStream());
|
||||
version = versionData.getProperty("version", version);
|
||||
version = version.trim().replaceAll("[^0-9\\.]", "");
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user