Specify the method which threw an exception when aborting
[ldk-java] / java_strings.py
index 6bfd571bbf991caa8b5be640b409ce0ab33ac1d3..f97ca9b7d0cff3ac4b416f175c8add0d10c9d040 100644 (file)
@@ -24,6 +24,12 @@ class Consts:
 
         self.bindings_header = """package org.ldk.impl;
 import org.ldk.enums.*;
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
 
 public class bindings {
        public static class VecOrSliceDef {
@@ -35,7 +41,24 @@ public class bindings {
                }
        }
        static {
-               System.loadLibrary(\"lightningjni\");
+               try {
+                       // Try to load natively first, this works on Android and in testing.
+                       System.loadLibrary(\"lightningjni\");
+               } catch (UnsatisfiedLinkError _ignored) {
+                       // Otherwise try to load from the library jar.
+                       File tmpdir = new File(System.getProperty("java.io.tmpdir"), "ldk-java-nativelib");
+                       tmpdir.mkdir(); // If it fails to create, assume it was there already
+                       tmpdir.deleteOnExit();
+                       String libname = "liblightningjni_" + System.getProperty("os.name").replaceAll(" ", "") +
+                               "-" + System.getProperty("os.arch").replaceAll(" ", "") + ".nativelib";
+                       try (InputStream is = bindings.class.getResourceAsStream("/" + libname)) {
+                               Path libpath = new File(tmpdir.toPath().toString(), "liblightningjni.so").toPath();
+                               Files.copy(is, libpath, StandardCopyOption.REPLACE_EXISTING);
+                               Runtime.getRuntime().load(libpath.toString());
+                       } catch (IOException e) {
+                               throw new IllegalArgumentException(e);
+                       }
+               }
                init(java.lang.Enum.class, VecOrSliceDef.class);
                init_class_cache();
                if (!get_lib_version_string().equals(get_ldk_java_bindings_version()))
@@ -831,6 +854,12 @@ import java.util.Arrays;
                     else:
                         out_c = out_c + ", " + arg_info.arg_name
                 out_c = out_c + ");\n"
+
+                out_c += "\tif ((*env)->ExceptionCheck(env)) {\n"
+                out_c += "\t\t(*env)->ExceptionDescribe(env);\n"
+                out_c += "\t\t(*env)->FatalError(env, \"A call to " + fn_line.fn_name + " in " + struct_name + " from rust threw an exception.\");\n"
+                out_c += "\t}\n"
+
                 if fn_line.ret_ty_info.arg_conv is not None:
                     out_c += "\t" + fn_line.ret_ty_info.arg_conv.replace("\n", "\n\t") + "\n"
                     out_c += "\t" + self.deconstruct_jenv().replace("\n", "\n\t").strip() + "\n"