Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
bundle the native library into the jar file
authorMartin Quinson <martin.quinson@loria.fr>
Wed, 5 Dec 2012 07:07:13 +0000 (08:07 +0100)
committerMartin Quinson <martin.quinson@loria.fr>
Wed, 5 Dec 2012 07:07:13 +0000 (08:07 +0100)
CMakeLists.txt
org/simgrid/msg/JniException.java
org/simgrid/msg/Msg.java

index e422592..88d42d6 100644 (file)
@@ -370,6 +370,17 @@ if(HAVE_TRACING)
   )
 endif(HAVE_TRACING)
 
+IF(CMAKE_SYSTEM_PROCESSOR MATCHES ".86")
+  IF(${ARCH_32_BITS})
+      set(JSG_BUNDLE NATIVE/${CMAKE_SYSTEM_NAME}/x86/)
+  ELSE()
+      set(JSG_BUNDLE NATIVE/${CMAKE_SYSTEM_NAME}/amd64/)
+  ENDIF()
+ELSE() 
+  error("Unknown system type. Processor: ${CMAKE_SYSTEM_PROCESSOR}; System: ${CMAKE_SYSTEM_NAME}")
+ENDIF()
+message("Native libraries bundeled into: ${JSG_BUNDLE}")
+
 # java_classes
 add_custom_command(
   OUTPUT  ${JAVA_SRC_CLASS}
@@ -377,6 +388,11 @@ add_custom_command(
   COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_HOME_DIRECTORY}/classes/"
   COMMAND ${JAVA_COMPILE} -d ${CMAKE_HOME_DIRECTORY}/classes/
     -cp ${CMAKE_HOME_DIRECTORY}/classes/ ${JAVA_SRC}
+  COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_HOME_DIRECTORY}/classes/${JSG_BUNDLE}
+  COMMAND ${CMAKE_COMMAND} -E copy ${SIMGRID_LIB_PATH}/libsimgrid.so ${CMAKE_HOME_DIRECTORY}/classes/${JSG_BUNDLE}
+  COMMAND strip --strip-debug ${CMAKE_HOME_DIRECTORY}/classes/${JSG_BUNDLE}/libsimgrid.so
+  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_HOME_DIRECTORY}/lib/libSG_java.so ${CMAKE_HOME_DIRECTORY}/classes/${JSG_BUNDLE}
+  COMMAND strip --strip-debug ${CMAKE_HOME_DIRECTORY}/classes/${JSG_BUNDLE}/libSG_java.so
   COMMENT "Compiling java sources of core library..."                                  
 )
 
index 9edada6..d9333a2 100644 (file)
@@ -32,4 +32,7 @@ public class JniException extends RuntimeException {
         */ public JniException(String s) {
                 super(s);
         }
+       public JniException(String string, Exception e) {
+               super(string,e);
+       }
 }
index 4cbf037..ba290f8 100644 (file)
 
 package org.simgrid.msg;
 
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.File;
+
+
 public final class Msg {
        /* Statically load the library which contains all native functions used in here */
        static {
                try {
+                       /* prefer the version on disk, if existing */
                        System.loadLibrary("SG_java");
-               } catch(UnsatisfiedLinkError e) {
+               } catch (UnsatisfiedLinkError e) {
+                       /* If not found, unpack the one bundled into the jar file and use it */
+                       loadLib("simgrid");
+                       loadLib("SG_java");
+               }
+       }
+       private static void loadLib (String name) {
+               String Path = "NATIVE/"+System.getProperty("os.name")+"/"+System.getProperty("os.arch")+"/";
+               String filename=name;
+               InputStream in = Msg.class.getClassLoader().getResourceAsStream(Path+filename);
+               
+               if (in == null) {
+                       filename = "lib"+name+".so";
+                       in = Msg.class.getClassLoader().getResourceAsStream(Path+filename);
+               } 
+               if (in == null) {
+                       filename = name+".dll";
+                       in = Msg.class.getClassLoader().getResourceAsStream(Path+filename);
+               }  
+               if (in == null) {
+                       filename = "lib"+name+".dylib";
+                       in = Msg.class.getClassLoader().getResourceAsStream(Path+filename);
+               }  
+               if (in == null) {
+                       throw new RuntimeException("Cannot find library "+name+" in path "+Path+". Sorry, but this jar does not seem to be usable on your machine.");
+               }
+// Caching the file on disk: desactivated because it could fool the users              
+//             if (new File(filename).isFile()) {
+//                     // file was already unpacked -- use it directly
+//                     System.load(new File(".").getAbsolutePath()+File.separator+filename);
+//                     return;
+//             }
+               try {
+                       // We must write the lib onto the disk before loading it -- stupid operating systems
+                       File fileOut = new File(filename);
+//                     if (!new File(".").canWrite()) {
+//                             System.out.println("Cannot write in ."+File.separator+filename+"; unpacking the library into a temporary file instead");
+                               fileOut = File.createTempFile("simgrid-", ".tmp");
+                               // don't leak the file on disk, but remove it on JVM shutdown
+                               Runtime.getRuntime().addShutdownHook(new Thread(new FileCleaner(fileOut.getAbsolutePath())));
+//                     }
+//                     System.out.println("Unpacking SimGrid native library to " + fileOut.getAbsolutePath());
+                       OutputStream out = new FileOutputStream(fileOut);
+                       
+                       /* copy the library in position */  
+                       byte[] buffer = new byte[4096]; 
+                       int bytes_read; 
+                       while ((bytes_read = in.read(buffer)) != -1)     // Read until EOF
+                               out.write(buffer, 0, bytes_read); 
+                     
+                       /* close all file descriptors, and load that shit */
+                       in.close();
+                       out.close();
+                       System.load(fileOut.getAbsolutePath());
+               } catch (Exception e) {
                        System.err.println("Cannot load the bindings to the simgrid library: ");
                        e.printStackTrace();
-                       System.err.println(
-                                       "Please check your LD_LIBRARY_PATH, or copy the simgrid and SG_java libraries to the current directory");
+                       System.err.println("This jar file does not seem to fit your system, sorry");
                        System.exit(1);
                }
+       }               
+       /* A hackish mechanism used to remove the file containing our library when the JVM shuts down */
+       private static class FileCleaner implements Runnable {
+               private String target;
+               public FileCleaner(String name) {
+                       target = name;
+               }
+        public void run() {
+            try {
+                new File(target).delete();
+            } catch(Exception e) {
+                System.out.println("Unable to clean temporary file "+target+" during shutdown.");
+                e.printStackTrace();
+            }
+        }    
        }
+
     /** Retrieve the simulation time
      * @return
      */