minor changes in executable jars: removed jdk dependency on simulating computer + temporary files from simulation are stored in a subdirectory + temporary files from building the jar are removed when done
This commit is contained in:
parent
b4a4572d97
commit
a45aa8e89c
|
@ -24,7 +24,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: GUI.java,v 1.148 2009/10/29 10:16:05 fros4943 Exp $
|
||||
* $Id: GUI.java,v 1.149 2009/10/29 17:05:13 fros4943 Exp $
|
||||
*/
|
||||
|
||||
package se.sics.cooja;
|
||||
|
@ -2595,7 +2595,7 @@ public class GUI extends Observable {
|
|||
* @return Value
|
||||
*/
|
||||
public static String getExternalToolsSetting(String name) {
|
||||
return currentExternalToolsSettings.getProperty(name);
|
||||
return getExternalToolsSetting(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4158,34 +4158,70 @@ public class GUI extends Observable {
|
|||
getSimulation().stopSimulation();
|
||||
|
||||
/* Info message */
|
||||
JOptionPane.showMessageDialog(GUI.getTopParentContainer(),
|
||||
String[] options = new String[] { "OK", "Cancel" };
|
||||
int n = JOptionPane.showOptionDialog(
|
||||
GUI.getTopParentContainer(),
|
||||
"This function attempts to build an executable COOJA JAR from the current simulation.\n" +
|
||||
"The JAR will contain all simulation dependencies, including project JAR files and mote firmware files.\n" +
|
||||
"\nExecutable simulations can be used to run already prepared simulations on several computers.\n" +
|
||||
"\nThis is an experimental feature!",
|
||||
"Export simulation to executable JAR", JOptionPane.INFORMATION_MESSAGE);
|
||||
"Export simulation to executable JAR", JOptionPane.OK_CANCEL_OPTION,
|
||||
JOptionPane.INFORMATION_MESSAGE, null, options, options[0]);
|
||||
if (n != JOptionPane.OK_OPTION) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Select output directory */
|
||||
/* Select output file */
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setDialogTitle("Select directory for " + ExecuteJAR.EXECUTABLE_JAR_FILENAME);
|
||||
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
fc.setAcceptAllFileFilterUsed(false);
|
||||
int returnVal = fc.showSaveDialog(myDesktopPane);
|
||||
FileFilter jarFilter = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
if (file.isDirectory()) {
|
||||
return true;
|
||||
}
|
||||
if (file.getName().endsWith(".jar")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public String getDescription() {
|
||||
return "Java archive";
|
||||
}
|
||||
public String toString() {
|
||||
return ".jar";
|
||||
}
|
||||
};
|
||||
fc.setFileFilter(jarFilter);
|
||||
fc.setSelectedFile(new File("cooja_simulation.jar"));
|
||||
int returnVal = fc.showSaveDialog(GUI.getTopParentContainer());
|
||||
if (returnVal != JFileChooser.APPROVE_OPTION) {
|
||||
return;
|
||||
}
|
||||
File dir = fc.getSelectedFile();
|
||||
if (!dir.isDirectory()) {
|
||||
return;
|
||||
File outputFile = fc.getSelectedFile();
|
||||
if (outputFile.exists()) {
|
||||
options = new String[] { "Overwrite", "Cancel" };
|
||||
n = JOptionPane.showOptionDialog(
|
||||
GUI.getTopParentContainer(),
|
||||
"A file with the same name already exists.\nDo you want to remove it?",
|
||||
"Overwrite existing file?", JOptionPane.YES_NO_OPTION,
|
||||
JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
|
||||
if (n != JOptionPane.YES_OPTION) {
|
||||
return;
|
||||
}
|
||||
outputFile.delete();
|
||||
}
|
||||
|
||||
try {
|
||||
ExecuteJAR.buildExecutableJAR(GUI.this, dir);
|
||||
} catch (RuntimeException ex) {
|
||||
JOptionPane.showMessageDialog(GUI.getTopParentContainer(),
|
||||
ex.getMessage(),
|
||||
"Mote type not supported", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
final File finalOutputFile = outputFile;
|
||||
new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
ExecuteJAR.buildExecutableJAR(GUI.this, finalOutputFile);
|
||||
} catch (RuntimeException ex) {
|
||||
JOptionPane.showMessageDialog(GUI.getTopParentContainer(),
|
||||
ex.getMessage(),
|
||||
"Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
public boolean shouldBeEnabled() {
|
||||
return getSimulation() != null;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: ExecuteJAR.java,v 1.1 2009/10/29 10:17:15 fros4943 Exp $
|
||||
* $Id: ExecuteJAR.java,v 1.2 2009/10/29 17:05:14 fros4943 Exp $
|
||||
*/
|
||||
|
||||
package se.sics.cooja.util;
|
||||
|
@ -32,6 +32,8 @@ package se.sics.cooja.util;
|
|||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.AccessControlException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Properties;
|
||||
|
@ -54,10 +56,8 @@ import se.sics.cooja.plugins.ScriptRunner;
|
|||
public class ExecuteJAR {
|
||||
private static Logger logger = Logger.getLogger(ExecuteJAR.class);
|
||||
|
||||
public final static String EXECUTABLE_JAR_FILENAME = "cooja_simulation.jar";
|
||||
public final static String EXTERNALTOOLS_FILENAME = "externaltools.config";
|
||||
public final static String SIMCONFIG_FILENAME = "simulation.csc";
|
||||
public final static String FIRMWARE_PREFIX = "firmware";
|
||||
public final static String EXTERNALTOOLS_FILENAME = "exttools.config";
|
||||
public final static String FIRMWARE_SUFFIX = ".sky";
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
@ -72,8 +72,7 @@ public class ExecuteJAR {
|
|||
}
|
||||
|
||||
if (args.length > 0) {
|
||||
/* Generate */
|
||||
logger.debug("Generating JAR");
|
||||
/* Generate executable JAR */
|
||||
if (args.length != 1) {
|
||||
throw new RuntimeException(
|
||||
"Bad command line arguments: specify only one simulation config!"
|
||||
|
@ -81,103 +80,140 @@ public class ExecuteJAR {
|
|||
}
|
||||
generate(new File(args[0]));
|
||||
} else {
|
||||
logger.debug("Executing JAR");
|
||||
/* Run simulation */
|
||||
execute();
|
||||
}
|
||||
}
|
||||
|
||||
private static void generate(File file) {
|
||||
if (!file.exists()) {
|
||||
private static void generate(File config) {
|
||||
if (!config.exists()) {
|
||||
throw new RuntimeException(
|
||||
"Simulation config not found: " + file.getAbsolutePath()
|
||||
"Simulation config not found: " + config.getAbsolutePath()
|
||||
);
|
||||
}
|
||||
|
||||
/* Load simulation */
|
||||
logger.debug("Loading " + file);
|
||||
Simulation s = GUI.quickStartSimulationConfig(file, false);
|
||||
logger.info("Loading " + config);
|
||||
Simulation s = GUI.quickStartSimulationConfig(config, false);
|
||||
if (s == null) {
|
||||
throw new RuntimeException(
|
||||
"Error when creating simulation"
|
||||
);
|
||||
}
|
||||
s.stopSimulation();
|
||||
logger.debug("Stopped simulation");
|
||||
|
||||
buildExecutableJAR(s.getGUI(), new File("."));
|
||||
buildExecutableJAR(s.getGUI(), new File(config.getName() + ".jar"));
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
|
||||
final static boolean OVERWRITE = false;
|
||||
private static void execute() {
|
||||
/* Execute */
|
||||
GUI.externalToolsUserSettingsFile = new File(EXTERNALTOOLS_FILENAME);
|
||||
String executeDir = null;
|
||||
try {
|
||||
executeDir = new File(
|
||||
ExecuteJAR.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getName();
|
||||
if (!executeDir.endsWith(".jar")) {
|
||||
logger.fatal("Not a proper JAR archive: " + executeDir);
|
||||
System.exit(1);
|
||||
}
|
||||
executeDir = executeDir.substring(0, executeDir.length()-".jar".length());
|
||||
new File(executeDir).mkdir();
|
||||
} catch (URISyntaxException e1) {
|
||||
logger.fatal("Can't access JAR file name: " + e1.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
/* Unpack JAR dependencies - only when they do not already exist! */
|
||||
try {
|
||||
Process process;
|
||||
if (!new File(SIMCONFIG_FILENAME).exists()) {
|
||||
logger.info("Unpacking simulation config: " + SIMCONFIG_FILENAME);
|
||||
process = Runtime.getRuntime().exec(new String[] {
|
||||
"jar",
|
||||
"xf",
|
||||
EXECUTABLE_JAR_FILENAME,
|
||||
SIMCONFIG_FILENAME,
|
||||
});
|
||||
process.waitFor();
|
||||
InputStream inputStream;
|
||||
File diskFile = new File(executeDir, SIMCONFIG_FILENAME);
|
||||
if (OVERWRITE || !diskFile.exists()) {
|
||||
logger.info("Unpacking simulation config: " + SIMCONFIG_FILENAME + " -> " + diskFile.getName());
|
||||
inputStream = GUI.class.getResourceAsStream("/" + SIMCONFIG_FILENAME);
|
||||
byte[] fileData = ArrayUtils.readFromStream(inputStream);
|
||||
if (fileData == null) {
|
||||
logger.info("Failed extracting file (read fail)");
|
||||
System.exit(1);
|
||||
}
|
||||
boolean ok = ArrayUtils.writeToFile(diskFile, fileData);
|
||||
if (!ok) {
|
||||
logger.info("Failed extracting file (write fail)");
|
||||
System.exit(1);
|
||||
}
|
||||
} else {
|
||||
logger.info("Skip: simulation config alrady exists: " + SIMCONFIG_FILENAME);
|
||||
logger.info("Skip: simulation config already exists: " + diskFile);
|
||||
}
|
||||
|
||||
if (!new File(EXTERNALTOOLS_FILENAME).exists()) {
|
||||
logger.info("Unpacking external tools config: " + EXTERNALTOOLS_FILENAME);
|
||||
process = Runtime.getRuntime().exec(new String[] {
|
||||
"jar",
|
||||
"xf",
|
||||
EXECUTABLE_JAR_FILENAME,
|
||||
EXTERNALTOOLS_FILENAME,
|
||||
});
|
||||
process.waitFor();
|
||||
diskFile = new File(executeDir, EXTERNALTOOLS_FILENAME);
|
||||
if (OVERWRITE || !diskFile.exists()) {
|
||||
logger.info("Unpacking external tools config: " + EXTERNALTOOLS_FILENAME + " -> " + diskFile.getName());
|
||||
inputStream = GUI.class.getResourceAsStream("/" + EXTERNALTOOLS_FILENAME);
|
||||
byte[] fileData = ArrayUtils.readFromStream(inputStream);
|
||||
if (fileData == null) {
|
||||
logger.info("Failed extracting file (read fail)");
|
||||
System.exit(1);
|
||||
}
|
||||
boolean ok = ArrayUtils.writeToFile(diskFile, fileData);
|
||||
if (!ok) {
|
||||
logger.info("Failed extracting file (write fail)");
|
||||
System.exit(1);
|
||||
}
|
||||
} else {
|
||||
logger.info("Skip: external tools config alrady exists: " + EXTERNALTOOLS_FILENAME);
|
||||
logger.info("Skip: external tools config already exists: " + diskFile);
|
||||
}
|
||||
GUI.externalToolsUserSettingsFile = diskFile;
|
||||
|
||||
if (!new File(FIRMWARE_PREFIX + 0 + FIRMWARE_SUFFIX).exists()) {
|
||||
logger.info("Unpacking firmware files (max 10))");
|
||||
process = Runtime.getRuntime().exec(new String[] {
|
||||
"jar",
|
||||
"xf",
|
||||
EXECUTABLE_JAR_FILENAME,
|
||||
FIRMWARE_PREFIX + 0 + FIRMWARE_SUFFIX,
|
||||
FIRMWARE_PREFIX + 1 + FIRMWARE_SUFFIX,
|
||||
FIRMWARE_PREFIX + 2 + FIRMWARE_SUFFIX,
|
||||
FIRMWARE_PREFIX + 3 + FIRMWARE_SUFFIX,
|
||||
FIRMWARE_PREFIX + 4 + FIRMWARE_SUFFIX,
|
||||
FIRMWARE_PREFIX + 5 + FIRMWARE_SUFFIX,
|
||||
FIRMWARE_PREFIX + 6 + FIRMWARE_SUFFIX,
|
||||
FIRMWARE_PREFIX + 7 + FIRMWARE_SUFFIX,
|
||||
FIRMWARE_PREFIX + 8 + FIRMWARE_SUFFIX,
|
||||
FIRMWARE_PREFIX + 9 + FIRMWARE_SUFFIX,
|
||||
});
|
||||
process.waitFor();
|
||||
} else {
|
||||
logger.info("Skip: firmware files already exist");
|
||||
int firmwareCounter = 0;
|
||||
while (true) {
|
||||
File firmwareFile = new File(firmwareCounter + FIRMWARE_SUFFIX);
|
||||
diskFile = new File(executeDir, firmwareCounter + FIRMWARE_SUFFIX);
|
||||
firmwareCounter++;
|
||||
if (OVERWRITE || !diskFile.exists()) {
|
||||
logger.info("Unpacking firmware file: " + firmwareFile.getName() + " -> " + diskFile.getName());
|
||||
inputStream = GUI.class.getResourceAsStream("/" + firmwareFile.getName());
|
||||
if (inputStream == null) {
|
||||
/* Not available in simulation */
|
||||
break;
|
||||
}
|
||||
byte[] fileData = ArrayUtils.readFromStream(inputStream);
|
||||
if (fileData == null) {
|
||||
logger.info("Failed extracting file (read fail)");
|
||||
System.exit(1);
|
||||
}
|
||||
boolean ok = ArrayUtils.writeToFile(diskFile, fileData);
|
||||
if (!ok) {
|
||||
logger.info("Failed extracting file (write fail)");
|
||||
System.exit(1);
|
||||
}
|
||||
} else {
|
||||
logger.info("Skip: firmware files already exist: " + diskFile);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error when partially unpacking executable JAR: " + e.getMessage());
|
||||
logger.fatal("Error when unpacking executable JAR: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info("Starting simulation");
|
||||
GUI.setLookAndFeel();
|
||||
GUI.quickStartSimulationConfig(new File(SIMCONFIG_FILENAME), false);
|
||||
GUI.quickStartSimulationConfig(new File(executeDir, SIMCONFIG_FILENAME), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds executable JAR from current simulation
|
||||
*
|
||||
* @param gui GUI. Must contain simulation
|
||||
* @param outputFile Output file
|
||||
*/
|
||||
public static void buildExecutableJAR(GUI gui, File outputDir) {
|
||||
public static boolean buildExecutableJAR(GUI gui, File outputFile) {
|
||||
String executeDir = null;
|
||||
executeDir = outputFile.getName();
|
||||
if (!executeDir.endsWith(".jar")) {
|
||||
throw new RuntimeException("Not a proper JAR archive: " + executeDir);
|
||||
}
|
||||
executeDir = executeDir.substring(0, executeDir.length()-".jar".length());
|
||||
|
||||
Simulation simulation = gui.getSimulation();
|
||||
if (simulation == null) {
|
||||
throw new RuntimeException(
|
||||
|
@ -267,7 +303,6 @@ public class ExecuteJAR {
|
|||
"Project JAR could not be found: " + jarFile.getAbsolutePath()
|
||||
);
|
||||
}
|
||||
|
||||
logger.info("Unpacking core JAR " + jar);
|
||||
try {
|
||||
Process unjarProcess = Runtime.getRuntime().exec(
|
||||
|
@ -299,7 +334,7 @@ public class ExecuteJAR {
|
|||
((Element)moteTypeElement).removeChildren("commands"); /* Remove build commands */
|
||||
for (Object pathElement : ((Element)moteTypeElement).getChildren()) {
|
||||
if (((Element) pathElement).getName().equals("firmware")) {
|
||||
String newName = FIRMWARE_PREFIX + firmwareCounter++ + FIRMWARE_SUFFIX;
|
||||
String newName = (firmwareCounter++) + FIRMWARE_SUFFIX;
|
||||
/* Copy firmwares, and update firmware references */
|
||||
String firmwarePath = ((Element)pathElement).getText();
|
||||
File firmwareFile = gui.restorePortablePath(new File(firmwarePath));
|
||||
|
@ -321,8 +356,8 @@ public class ExecuteJAR {
|
|||
"Error when writing firmware file: " + firmwareFile
|
||||
);
|
||||
}
|
||||
logger.info("Simconfig: Update firmware path reference: " + firmwareFile.getAbsolutePath() + " -> " + newName);
|
||||
((Element)pathElement).setText(newName);
|
||||
logger.info("Simconfig: Update firmware path reference: " + firmwareFile.getAbsolutePath() + " -> " + (executeDir + "/" + newName));
|
||||
((Element)pathElement).setText(executeDir + "/" + newName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -344,12 +379,11 @@ public class ExecuteJAR {
|
|||
"Error when writing simulation configuration: " + configFile
|
||||
).initCause(e1);
|
||||
}
|
||||
logger.info("Wrote simulation configuration: " + configFile.getAbsolutePath());
|
||||
logger.info("Wrote simulation configuration: " + configFile.getName());
|
||||
|
||||
/* Export external tools config (without projects) */
|
||||
try {
|
||||
File externalToolsConfig = new File(workingDir, EXTERNALTOOLS_FILENAME);
|
||||
logger.info("Exporting external tools config: " + externalToolsConfig);
|
||||
FileOutputStream out = new FileOutputStream(externalToolsConfig);
|
||||
Properties differingSettings = new Properties();
|
||||
Enumeration<Object> keyEnum = GUI.currentExternalToolsSettings.keys();
|
||||
|
@ -367,6 +401,7 @@ public class ExecuteJAR {
|
|||
|
||||
differingSettings.store(out, "COOJA External Tools (User specific)");
|
||||
out.close();
|
||||
logger.info("Wrote external tools config: " + externalToolsConfig.getName());
|
||||
} catch (Exception e2) {
|
||||
throw (RuntimeException) new RuntimeException(
|
||||
"Error when writing external tools configuration: " + e2.getMessage()
|
||||
|
@ -378,23 +413,22 @@ public class ExecuteJAR {
|
|||
if (manifestFile.exists()) {
|
||||
manifestFile.delete();
|
||||
}
|
||||
logger.info("Creating manifest file: " + manifestFile);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Manifest-Version: 1.0\r\n");
|
||||
sb.append("Main-Class: " + ExecuteJAR.class.getName() + "\r\n");
|
||||
sb.append("Class-path: .\r\n");
|
||||
StringUtils.saveToFile(manifestFile, sb.toString());
|
||||
logger.info("Wrote manifest file: " + manifestFile.getName());
|
||||
|
||||
/* Build executable JAR */
|
||||
File executableJAR = new File(outputDir, EXECUTABLE_JAR_FILENAME);
|
||||
if (executableJAR.exists()) {
|
||||
executableJAR.delete();
|
||||
if (outputFile.exists()) {
|
||||
outputFile.delete();
|
||||
}
|
||||
|
||||
logger.info("Building executable JAR: " + executableJAR);
|
||||
logger.info("Building executable JAR: " + outputFile);
|
||||
try {
|
||||
Process jarProcess = Runtime.getRuntime().exec(
|
||||
new String[] { "jar", "cfm", executableJAR.getAbsolutePath(), "manifest.tmp", "*"},
|
||||
new String[] { "jar", "cfm", outputFile.getAbsolutePath(), "manifest.tmp", "*"},
|
||||
null,
|
||||
workingDir
|
||||
);
|
||||
|
@ -405,8 +439,31 @@ public class ExecuteJAR {
|
|||
).initCause(e1);
|
||||
}
|
||||
|
||||
/* Delete temporary working directory */
|
||||
logger.info("Deleting temporary files in: " + workingDir.getAbsolutePath());
|
||||
if (!deleteDirectory(workingDir)) {
|
||||
if (!deleteDirectory(workingDir)) {
|
||||
deleteDirectory(workingDir);
|
||||
}
|
||||
}
|
||||
|
||||
/* We are done! */
|
||||
logger.info("Done! You may remove the temporary working directory: " + workingDir.getAbsolutePath());
|
||||
logger.info("Run simulation: > java -jar " + EXECUTABLE_JAR_FILENAME);
|
||||
logger.info("Done! To run simulation: > java -jar " + outputFile.getName());
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean deleteDirectory(File path) {
|
||||
if(path.exists()) {
|
||||
File[] files = path.listFiles();
|
||||
for(File file: files) {
|
||||
if(file.isDirectory()) {
|
||||
deleteDirectory(file);
|
||||
} else {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
return(path.delete());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue