From 0eba920ca4a67c6b52f79c81ce0170a0bfadae48 Mon Sep 17 00:00:00 2001 From: 4pr0n Date: Tue, 8 Apr 2014 23:33:26 -0700 Subject: [PATCH] Updating is more verbose, has more error handling --- pom.xml | 7 +- .../com/rarchives/ripme/ui/UpdateUtils.java | 102 ++++++++++++++---- 2 files changed, 86 insertions(+), 23 deletions(-) diff --git a/pom.xml b/pom.xml index cbbb3f5d..d1588f3f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.rarchives.ripme ripme jar - 1.0.11 + 1.0.13 ripme http://rip.rarchives.com @@ -43,6 +43,11 @@ commons-cli 1.2 + + org.apache.commons + commons-io + 1.3.2 + diff --git a/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java b/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java index b1977525..e5bbb73c 100644 --- a/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java +++ b/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java @@ -1,5 +1,6 @@ package com.rarchives.ripme.ui; +import java.awt.Desktop; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -7,6 +8,7 @@ import java.io.IOException; import javax.swing.JLabel; import javax.swing.JOptionPane; +import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; import org.json.JSONArray; import org.json.JSONObject; @@ -17,7 +19,7 @@ import org.jsoup.nodes.Document; public class UpdateUtils { private static final Logger logger = Logger.getLogger(UpdateUtils.class); - private static final String DEFAULT_VERSION = "1.0.11"; + private static final String DEFAULT_VERSION = "1.0.13"; private static final String updateJsonURL = "http://rarchives.com/ripme.json"; private static final String updateJarURL = "http://rarchives.com/ripme.jar"; private static final String mainFileName = "ripme.jar"; @@ -76,7 +78,7 @@ public class UpdateUtils { configUpdateLabel.setText("Downloading new version..."); logger.info("New version found, downloading..."); try { - UpdateUtils.downloadJarAndReplace(updateJarURL); + UpdateUtils.downloadJarAndLaunch(updateJarURL); } catch (IOException e) { JOptionPane.showMessageDialog(null, "Error while updating: " + e.getMessage(), @@ -129,7 +131,7 @@ public class UpdateUtils { return intVersions; } - private static void downloadJarAndReplace(String updateJarURL) + private static void downloadJarAndLaunch(String updateJarURL) throws IOException { Response response; response = Jsoup.connect(updateJarURL) @@ -140,40 +142,96 @@ public class UpdateUtils { FileOutputStream out = new FileOutputStream(updateFileName); out.write(response.bodyAsBytes()); out.close(); - Runtime.getRuntime().exec(new String[] {"java", "-jar", updateFileName}); + logger.info("Download of new version complete; saved to " + updateFileName); + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + try { + logger.info("Executing: java -jar " + updateFileName); + Runtime.getRuntime().exec(new String[] {"java", "-jar", updateFileName}); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + logger.info("Exiting older version, should execute updated jar (" + updateFileName + ") during exit"); System.exit(0); } public static void moveUpdatedJar() { - File newFile = new File(updateFileName); - File oldFile = new File(mainFileName); + // Copy the new file (ripme.jar.update) to original location (ripme.jar) + // Delete new file (update) on exit + // Exit + File newFile = new File(updateFileName); // ripme.jar.update + File oldFile = new File(mainFileName); // ripme.jar if (!newFile.exists()) { // Can't update without .update file return; } - if (oldFile.exists()) { - logger.info("Deleting existing .jar file: " + oldFile); + + // Attempt to copy new .jar file over old jar file. + int retries = 3; + while (true) { + retries--; try { - oldFile.delete(); - } catch (Exception e) { - logger.error("Failed to delete old jar file: " + oldFile); + logger.info("Updated .jar file '" + newFile + "' exists, overwriting older version at " + oldFile + " ..."); + FileUtils.copyFile(newFile, oldFile); + break; // Copy was successful; break. + } + catch (IOException e) { + logger.error("Failed to copy the updated jar over the original jar.\nUpdated Jar:\t" + newFile + "\nOriginal Jar: " + oldFile); + if (retries < 0) { + // We failed! + // Show error messages, pop up message dialog, and open the directory containing jars + logger.error("Cannot ovewrite existing jar file " + oldFile + " with updated file " + newFile + " ... Please update by moving files manually"); + try { + Desktop.getDesktop().open(newFile.getParentFile()); + } catch (IOException ioe) { + logger.error("Error while opening directory " + newFile.getParentFile(), ioe); + } + JOptionPane.showMessageDialog(null, + "Failed to copy the updated .jar file over the original .jar file\nUpdated Jar:\t" + newFile + "\nOriginal Jar: " + oldFile + "\n\nPlease update by moving files manually", + "RipMe Updater Error", + JOptionPane.ERROR_MESSAGE); + System.exit(1); + return; + } + e.printStackTrace(); + try { + logger.warn("Waiting 1 second, copy retries remaining: " + retries); + Thread.sleep(1000); + } catch (InterruptedException ie) { + logger.error("Interrupted while waiting for original jar " + oldFile + " to be overwritten", ie); + return; + } + } + } + + // Delete the updated .jar on exit + if (newFile.exists()) { + logger.info("Will delete '" + newFile + "' on exit"); + try { + FileUtils.forceDeleteOnExit(newFile); + } + catch (Exception e) { + logger.error("Failed to schedule delete on file: " + newFile); return; } } - boolean success = newFile.renameTo(oldFile); - - if (!success) { - logger.error("Failed to rename file from " + newFile.getAbsolutePath() + " to " + oldFile.getAbsolutePath()); - return; - } + // Execute the copied, updated .jar at ripme.jar try { - logger.debug("Executing jar " + oldFile.getName()); - Runtime.getRuntime().exec(new String[] {"java", "-jar", oldFile.getName()}); - logger.info("Started new version, quitting old version..."); + String[] command = new String[] { + "java", + "-jar", + oldFile.getName() }; + logger.info("Executing: " + command[0] + " " + command[1] + " " + command[2]); + Runtime.getRuntime().exec(command); + logger.info("Started new version at " + oldFile.getName() + ", quitting current program..."); System.exit(0); - } catch (IOException e) { - logger.error("Error while executing new jar " + newFile, e); + } + catch (IOException e) { + logger.error("Error while executing new jar '" + oldFile.getName() + "'", e); return; } }