From: Martin Quinson Date: Wed, 5 Dec 2012 07:07:13 +0000 (+0100) Subject: bundle the native library into the jar file X-Git-Tag: v3_9_90~569^2~19^2~9^2~6 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/6bee07c05481cf59f8e8dbaff46629af3d254c06?hp=13be40eff6b05494529813d4c953dda7a03920c0 bundle the native library into the jar file --- diff --git a/CMakeLists.txt b/CMakeLists.txt index e422592d4e..88d42d6533 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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..." ) diff --git a/org/simgrid/msg/JniException.java b/org/simgrid/msg/JniException.java index 9edada6612..d9333a28e4 100644 --- a/org/simgrid/msg/JniException.java +++ b/org/simgrid/msg/JniException.java @@ -32,4 +32,7 @@ public class JniException extends RuntimeException { */ public JniException(String s) { super(s); } + public JniException(String string, Exception e) { + super(string,e); + } } diff --git a/org/simgrid/msg/Msg.java b/org/simgrid/msg/Msg.java index 4cbf037478..ba290f864a 100644 --- a/org/simgrid/msg/Msg.java +++ b/org/simgrid/msg/Msg.java @@ -11,19 +11,95 @@ 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 */