summaryrefslogtreecommitdiff
path: root/src/cz/crcs/ectester/standalone/libs/NativeECLibrary.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cz/crcs/ectester/standalone/libs/NativeECLibrary.java')
-rw-r--r--src/cz/crcs/ectester/standalone/libs/NativeECLibrary.java119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/cz/crcs/ectester/standalone/libs/NativeECLibrary.java b/src/cz/crcs/ectester/standalone/libs/NativeECLibrary.java
new file mode 100644
index 0000000..0a420a1
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/libs/NativeECLibrary.java
@@ -0,0 +1,119 @@
+package cz.crcs.ectester.standalone.libs;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.security.Provider;
+
+/**
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public abstract class NativeECLibrary extends ProviderECLibrary {
+ private String resource;
+ private String[] requriements;
+
+ public static String LIB_RESOURCE_DIR = "/cz/crcs/ectester/standalone/libs/jni/";
+
+ public NativeECLibrary(String resource, String... requirements) {
+ this.resource = resource;
+ this.requriements = requirements;
+ }
+
+ @Override
+ public boolean initialize() {
+ try {
+ /* Determine what OS are we running on and use appropriate suffix and path. */
+ String suffix;
+ Path appData;
+ if (System.getProperty("os.name").startsWith("Windows")) {
+ suffix = "dll";
+ appData = Paths.get(System.getenv("AppData"));
+ } else {
+ suffix = "so";
+ if (System.getProperty("os.name").startsWith("Linux")) {
+ String dataHome = System.getenv("XDG_DATA_HOME");
+ if (dataHome != null) {
+ appData = Paths.get(dataHome);
+ } else {
+ appData = Paths.get(System.getProperty("user.home"), ".local", "share");
+ }
+ } else {
+ appData = Paths.get(System.getProperty("user.home"), ".local", "share");
+ }
+ }
+ Path libDir = appData.resolve("ECTesterStandalone");
+ File libDirFile = libDir.toFile();
+ Path libPath = libDir.resolve(resource + "." + suffix);
+ File libFile = libPath.toFile();
+
+ URL jarURL = NativeECLibrary.class.getResource(LIB_RESOURCE_DIR + resource + "." + suffix);
+ if (jarURL == null) {
+ return false;
+ }
+ URLConnection jarConnection = jarURL.openConnection();
+
+ /* Only write the file if it does not exist,
+ * or if the existing one is older than the
+ * one in the JAR.
+ */
+ boolean write = false;
+ if (libDirFile.isDirectory() && libFile.isFile()) {
+ long jarModified = jarConnection.getLastModified();
+
+ long libModified = Files.getLastModifiedTime(libPath).toMillis();
+ if (jarModified > libModified) {
+ write = true;
+ }
+ } else {
+ libDir.toFile().mkdirs();
+ libFile.createNewFile();
+ write = true;
+ }
+
+ if (write) {
+ Files.copy(jarConnection.getInputStream(), libPath, StandardCopyOption.REPLACE_EXISTING);
+ }
+ jarConnection.getInputStream().close();
+
+ /*
+ * Need to hack in /usr/local/lib to path.
+ * See: https://stackoverflow.com/questions/5419039/is-djava-library-path-equivalent-to-system-setpropertyjava-library-path/24988095#24988095
+ */
+ String path = System.getProperty("java.library.path");
+ if (suffix.equals("so")) {
+ String newPath = path + ":/usr/local/lib";
+ System.setProperty("java.library.path", newPath);
+ Field fieldSysPath;
+ try {
+ fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" );
+ fieldSysPath.setAccessible( true );
+ fieldSysPath.set( null, null );
+ } catch (NoSuchFieldException | IllegalAccessException ignored) {
+ }
+ }
+
+ for (String requirement : requriements) {
+ System.loadLibrary(requirement);
+ }
+
+ if (suffix.equals("so")) {
+ System.setProperty("java.library.path", path);
+ }
+
+ System.load(libPath.toString());
+
+ provider = createProvider();
+ return super.initialize();
+ } catch (IOException | UnsatisfiedLinkError ignored) {
+ }
+ return false;
+ }
+
+ abstract Provider createProvider();
+}