/* This code is part of Freenet. It is distributed under the GNU General
* Public License, version 2 (or at your option any later version). See
* http://www.gnu.org/ for further details of the GPL. */
package freenet.support;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
/**
* A simple class to load native libraries from the -ext jarfile
*
* @author Florent Daignière <nextgens@freenetproject.org>
*
* TODO: make it more generic so that all libraries can use it (bigint, jcpuid, fec, ...)
*/
public class LibraryLoader {
public static String getSimplifiedArchitecture() {
String _os_arch =System.getProperty("os.arch").toLowerCase();
String arch;
if(_os_arch.matches("(i?[x0-9]86_64|amd64)")) {
arch = "amd64";
} else if(_os_arch.matches("(arm)")) {
arch = "arm";
} else if(_os_arch.matches("(ppc)")) {
arch = "ppc";
} else {
// We want to try the i386 libraries if the architecture is unknown
// Wrappers MUST fallback to "plain java" implementation if loading native libraries fails
arch = "i386";
}
return arch;
}
public static boolean loadNative(String path, String libraryName) {
boolean success = false;
final boolean isWindows = File.pathSeparatorChar == ';';
final String prefix = (isWindows ? ".dll" : ((System.getProperty("os.name")).toLowerCase().startsWith("mac") ? ".jnilib" : ".so"));
final String libraryNameWithPrefix = (isWindows ? "" : "lib") + libraryName;
final String libraryNameWithPrefixAndArch = libraryNameWithPrefix + '-' + getSimplifiedArchitecture();
final String libraryNameWithPrefixAndArchAndSuffix = libraryNameWithPrefixAndArch + prefix;
String resourceName = path + libraryNameWithPrefixAndArchAndSuffix;
File nativeLib = new File((System.getProperty("java.library.path")) + "/lib" + libraryName + prefix);
if (nativeLib.exists()) {
System.out.println("Attempting to load the NativeThread library ["+libraryName+']');
System.loadLibrary(libraryName);
success = true;
} else {
try {
// Get the resource
URL resource = LibraryLoader.class.getResource(resourceName);
// Get input stream from jar resource
InputStream inputStream = resource.openStream();
// Copy resource to filesystem in a temp folder with a unique name
File temporaryLib = File.createTempFile(libraryNameWithPrefixAndArch, ".tmp");
// Delete on exit the dll
temporaryLib.deleteOnExit();
FileOutputStream outputStream = new FileOutputStream(temporaryLib);
byte[] array = new byte[2048];
int read = 0;
while((read = inputStream.read(array)) > 0) {
outputStream.write(array, 0, read);
}
outputStream.close();
// Finally, load the dll
System.out.println("Attempting to load the "+libraryName+" library ["+resource+']');
System.load(temporaryLib.getPath());
success = true;
} catch(Throwable e) {
System.err.println("Caught the following exception attempting to load "+resourceName);
e.printStackTrace();
}
}
return success;
}
}