Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
c06adb312a950c6ad984a35ff559640c5e7f4d7e
[simgrid.git] / src / bindings / java / 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 Os = System.getProperty("os.name");
41                 String Arch = System.getProperty("os.arch");
42                 // Some OS/Arch may be different between Java and Cmake,
43                 // which generated the path
44                 if (Os.toLowerCase().startsWith("win"))
45                         Os = "Windows";
46                 else if (Os.contains("OS X"))
47                         Os = "Darwin";
48                 if (Arch.equalsIgnoreCase("x86"))
49                         Arch = "i386";
50                 else if (Arch.equalsIgnoreCase("x86_64"))
51                         Arch = "amd64";
52                 String Path = "NATIVE/" + Os + "/" + Arch + "/";
53
54                 String filename=name;
55                 InputStream in = Msg.class.getClassLoader().getResourceAsStream(Path+filename);
56                 
57                 if (in == null) {
58                         filename = "lib"+name+".so";
59                         in = Msg.class.getClassLoader().getResourceAsStream(Path+filename);
60                 } 
61                 if (in == null) {
62                         filename = name+".dll";
63                         in = Msg.class.getClassLoader().getResourceAsStream(Path+filename);
64                 }  
65                 if (in == null) {
66                         filename = "lib"+name+".dll";
67                         in = Msg.class.getClassLoader().getResourceAsStream(Path+filename);
68                 }  
69                 if (in == null) {
70                         filename = "lib"+name+".dylib";
71                         in = Msg.class.getClassLoader().getResourceAsStream(Path+filename);
72                 }  
73                 if (in == null) {
74                         throw new RuntimeException("Cannot find library "+name+" in path "+Path+". Sorry, but this jar does not seem to be usable on your machine.");
75                 }
76 // Caching the file on disk: desactivated because it could fool the users               
77 //              if (new File(filename).isFile()) {
78 //                      // file was already unpacked -- use it directly
79 //                      System.load(new File(".").getAbsolutePath()+File.separator+filename);
80 //                      return;
81 //              }
82                 try {
83                         // We must write the lib onto the disk before loading it -- stupid operating systems
84                         File fileOut = new File(filename);
85 //                      if (!new File(".").canWrite()) {
86 //                              System.out.println("Cannot write in ."+File.separator+filename+"; unpacking the library into a temporary file instead");
87                                 fileOut = File.createTempFile("simgrid-", ".tmp");
88                                 // don't leak the file on disk, but remove it on JVM shutdown
89                                 Runtime.getRuntime().addShutdownHook(new Thread(new FileCleaner(fileOut.getAbsolutePath())));
90 //                      }
91 //                      System.out.println("Unpacking SimGrid native library to " + fileOut.getAbsolutePath());
92                         OutputStream out = new FileOutputStream(fileOut);
93                         
94                         /* copy the library in position */  
95                         byte[] buffer = new byte[4096]; 
96                         int bytes_read; 
97                         while ((bytes_read = in.read(buffer)) != -1)     // Read until EOF
98                                 out.write(buffer, 0, bytes_read); 
99                       
100                         /* close all file descriptors, and load that shit */
101                         in.close();
102                         out.close();
103                         System.load(fileOut.getAbsolutePath());
104                 } catch (Exception e) {
105                         System.err.println("Cannot load the bindings to the simgrid library: ");
106                         e.printStackTrace();
107                         System.err.println("This jar file does not seem to fit your system, sorry");
108                         System.exit(1);
109                 }
110         }               
111         /* A hackish mechanism used to remove the file containing our library when the JVM shuts down */
112         private static class FileCleaner implements Runnable {
113                 private String target;
114                 public FileCleaner(String name) {
115                         target = name;
116                 }
117         public void run() {
118             try {
119                 new File(target).delete();
120             } catch(Exception e) {
121                 System.out.println("Unable to clean temporary file "+target+" during shutdown.");
122                 e.printStackTrace();
123             }
124         }    
125         }
126
127     /** Retrieve the simulation time
128      * @return The simulation time.
129      */
130         public final static native double getClock();
131         /**
132          * Issue a debug logging message.
133          * @param s message to log.
134          */
135         public final static native void debug(String s);
136         /**
137          * Issue an verbose logging message.
138          * @param s message to log.
139          */
140         public final static native void verb(String s);
141
142         /** Issue an information logging message
143      * @param s
144      */
145         public final static native void info(String s);
146         /**
147          * Issue an warning logging message.
148          * @param s message to log.
149          */
150         public final static native void warn(String s);
151         /**
152          * Issue an error logging message.
153          * @param s message to log.
154          */
155         public final static native void error(String s);
156         /**
157          * Issue an critical logging message.
158          * @param s message to log.
159          */
160         public final static native void critical(String s);
161
162         /*********************************************************************************
163          * Deployment and initialization related functions                               *
164          *********************************************************************************/
165
166         /**
167          * The natively implemented method to initialize a MSG simulation.
168          *
169          * @param args            The arguments of the command line of the simulation.
170          */
171         public final static native void init(String[]args);
172
173         /**
174          * Run the MSG simulation.
175          *
176          * The simulation is not cleaned afterward (see  
177          * {@link #clean()} if you really insist on cleaning the C side), so you can freely 
178          * retrieve the informations that you want from the simulation. In particular, retrieving the status 
179          * of a process or the current date is perfectly ok. 
180          */
181         public final static native void run() ;
182         
183         /** This function is useless nowadays, just stop calling it. */
184         @Deprecated
185         public final static void clean(){}
186
187         /**
188          * The native implemented method to create the environment of the simulation.
189          *
190          * @param platformFile    The XML file which contains the description of the environment of the simulation
191          *
192          */
193         public final static native void createEnvironment(String platformFile);
194
195         /**
196          * The method to deploy the simulation.
197          *
198      *
199      * @param deploymentFile
200      */
201         public final static native void deployApplication(String deploymentFile);
202
203     /** Example launcher. You can use it or provide your own launcher, as you wish
204      * @param args
205      * @throws MsgException
206      */
207         static public void main(String[]args) throws MsgException {
208                 /* initialize the MSG simulation. Must be done before anything else (even logging). */
209                 Msg.init(args);
210
211                 if (args.length < 2) {
212                         Msg.info("Usage: Msg platform_file deployment_file");
213                         System.exit(1);
214                 }
215
216                 /* Load the platform and deploy the application */
217                 Msg.createEnvironment(args[0]);
218                 Msg.deployApplication(args[1]);
219                 /* Execute the simulation */
220                 Msg.run();
221         }
222 }