Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
ensures that the native libraries are always loaded before trying to access them
[simgrid.git] / org / simgrid / msg / Msg.java
1 /*
2  * JNI interface to C code for MSG.
3  * 
4  * Copyright 2006-2012 The SimGrid Team.           
5  * All right reserved. 
6  *
7  * This program is free software; you can redistribute 
8  * it and/or modify it under the terms of the license 
9  * (GNU LGPL) which comes with this package.
10  */
11
12 package org.simgrid.msg;
13
14 import java.io.FileOutputStream;
15 import java.io.InputStream;
16 import java.io.OutputStream;
17 import java.io.File;
18
19
20 public final class Msg {
21         /* Statically load the library which contains all native functions used in here */
22         static private boolean isNativeInited = false;
23         public static void nativeInit() {
24                 if (isNativeInited)
25                         return;
26                 try {
27                         /* prefer the version on disk, if existing */
28                         System.loadLibrary("SG_java");
29                 } catch (UnsatisfiedLinkError e) {
30                         /* If not found, unpack the one bundled into the jar file and use it */
31                         loadLib("simgrid");
32                         loadLib("SG_java");
33                 }
34                 isNativeInited = true;
35         }
36         static {
37                 nativeInit();
38         }
39         private static void loadLib (String name) {
40                 String Path = "NATIVE/"+System.getProperty("os.name")+"/"+System.getProperty("os.arch")+"/";
41                 String filename=name;
42                 InputStream in = Msg.class.getClassLoader().getResourceAsStream(Path+filename);
43                 
44                 if (in == null) {
45                         filename = "lib"+name+".so";
46                         in = Msg.class.getClassLoader().getResourceAsStream(Path+filename);
47                 } 
48                 if (in == null) {
49                         filename = name+".dll";
50                         in = Msg.class.getClassLoader().getResourceAsStream(Path+filename);
51                 }  
52                 if (in == null) {
53                         filename = "lib"+name+".dylib";
54                         in = Msg.class.getClassLoader().getResourceAsStream(Path+filename);
55                 }  
56                 if (in == null) {
57                         throw new RuntimeException("Cannot find library "+name+" in path "+Path+". Sorry, but this jar does not seem to be usable on your machine.");
58                 }
59 // Caching the file on disk: desactivated because it could fool the users               
60 //              if (new File(filename).isFile()) {
61 //                      // file was already unpacked -- use it directly
62 //                      System.load(new File(".").getAbsolutePath()+File.separator+filename);
63 //                      return;
64 //              }
65                 try {
66                         // We must write the lib onto the disk before loading it -- stupid operating systems
67                         File fileOut = new File(filename);
68 //                      if (!new File(".").canWrite()) {
69 //                              System.out.println("Cannot write in ."+File.separator+filename+"; unpacking the library into a temporary file instead");
70                                 fileOut = File.createTempFile("simgrid-", ".tmp");
71                                 // don't leak the file on disk, but remove it on JVM shutdown
72                                 Runtime.getRuntime().addShutdownHook(new Thread(new FileCleaner(fileOut.getAbsolutePath())));
73 //                      }
74 //                      System.out.println("Unpacking SimGrid native library to " + fileOut.getAbsolutePath());
75                         OutputStream out = new FileOutputStream(fileOut);
76                         
77                         /* copy the library in position */  
78                         byte[] buffer = new byte[4096]; 
79                         int bytes_read; 
80                         while ((bytes_read = in.read(buffer)) != -1)     // Read until EOF
81                                 out.write(buffer, 0, bytes_read); 
82                       
83                         /* close all file descriptors, and load that shit */
84                         in.close();
85                         out.close();
86                         System.load(fileOut.getAbsolutePath());
87                 } catch (Exception e) {
88                         System.err.println("Cannot load the bindings to the simgrid library: ");
89                         e.printStackTrace();
90                         System.err.println("This jar file does not seem to fit your system, sorry");
91                         System.exit(1);
92                 }
93         }               
94         /* A hackish mechanism used to remove the file containing our library when the JVM shuts down */
95         private static class FileCleaner implements Runnable {
96                 private String target;
97                 public FileCleaner(String name) {
98                         target = name;
99                 }
100         public void run() {
101             try {
102                 new File(target).delete();
103             } catch(Exception e) {
104                 System.out.println("Unable to clean temporary file "+target+" during shutdown.");
105                 e.printStackTrace();
106             }
107         }    
108         }
109
110     /** Retrieve the simulation time
111      * @return
112      */
113         public final static native double getClock();
114         /**
115          * Issue a debug logging message.
116          * @param s message to log.
117          */
118         public final static native void debug(String s);
119         /**
120          * Issue an verbose logging message.
121          * @param s message to log.
122          */
123         public final static native void verb(String s);
124
125         /** Issue an information logging message
126      * @param s
127      */
128         public final static native void info(String s);
129         /**
130          * Issue an warning logging message.
131          * @param s message to log.
132          */
133         public final static native void warn(String s);
134         /**
135          * Issue an error logging message.
136          * @param s message to log.
137          */
138         public final static native void error(String s);
139         /**
140          * Issue an critical logging message.
141          * @param s message to log.
142          */
143         public final static native void critical(String s);
144
145         /*********************************************************************************
146          * Deployment and initialization related functions                               *
147          *********************************************************************************/
148
149         /**
150          * The natively implemented method to initialize a MSG simulation.
151          *
152          * @param args            The arguments of the command line of the simulation.
153          *
154          * @see                    Msg.init()
155          */
156         public final static native void init(String[]args);
157
158         /**
159          * Run the MSG simulation.
160          *
161          * The simulation is not cleaned afterward (see  
162          * {@link #clean()} if you really insist on cleaning the C side), so you can freely 
163          * retrieve the informations that you want from the simulation. In particular, retrieving the status 
164          * of a process or the current date is perfectly ok. 
165          *
166          * @see                    MSG_run
167          */
168         public final static native void run() ;
169         
170         /** This function is useless nowadays, just stop calling it. */
171         @Deprecated
172         public final static void clean(){}
173
174         /**
175          * The native implemented method to create the environment of the simulation.
176          *
177          * @param platformFile    The XML file which contains the description of the environment of the simulation
178          *
179          */
180         public final static native void createEnvironment(String platformFile);
181
182         /**
183          * The method to deploy the simulation.
184          *
185      *
186      * @param deploymentFile
187      */
188         public final static native void deployApplication(String deploymentFile);
189
190     /** Example launcher. You can use it or provide your own launcher, as you wish
191      * @param args
192      * @throws MsgException
193      */
194         static public void main(String[]args) throws MsgException {
195                 /* initialize the MSG simulation. Must be done before anything else (even logging). */
196                 Msg.init(args);
197
198                 if (args.length < 2) {
199                         Msg.info("Usage: Msg platform_file deployment_file");
200                         System.exit(1);
201                 }
202
203                 /* Load the platform and deploy the application */
204                 Msg.createEnvironment(args[0]);
205                 Msg.deployApplication(args[1]);
206                 /* Execute the simulation */
207                 Msg.run();
208         }
209 }