Updating is more verbose, has more error handling

This commit is contained in:
4pr0n 2014-04-08 23:33:26 -07:00
parent 7f390962b6
commit 0eba920ca4
2 changed files with 86 additions and 23 deletions

View File

@ -4,7 +4,7 @@
<groupId>com.rarchives.ripme</groupId> <groupId>com.rarchives.ripme</groupId>
<artifactId>ripme</artifactId> <artifactId>ripme</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>1.0.11</version> <version>1.0.13</version>
<name>ripme</name> <name>ripme</name>
<url>http://rip.rarchives.com</url> <url>http://rip.rarchives.com</url>
<properties> <properties>
@ -43,6 +43,11 @@
<artifactId>commons-cli</artifactId> <artifactId>commons-cli</artifactId>
<version>1.2</version> <version>1.2</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>

View File

@ -1,5 +1,6 @@
package com.rarchives.ripme.ui; package com.rarchives.ripme.ui;
import java.awt.Desktop;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
@ -7,6 +8,7 @@ import java.io.IOException;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
@ -17,7 +19,7 @@ import org.jsoup.nodes.Document;
public class UpdateUtils { public class UpdateUtils {
private static final Logger logger = Logger.getLogger(UpdateUtils.class); 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 updateJsonURL = "http://rarchives.com/ripme.json";
private static final String updateJarURL = "http://rarchives.com/ripme.jar"; private static final String updateJarURL = "http://rarchives.com/ripme.jar";
private static final String mainFileName = "ripme.jar"; private static final String mainFileName = "ripme.jar";
@ -76,7 +78,7 @@ public class UpdateUtils {
configUpdateLabel.setText("<html><font color=\"green\">Downloading new version...</font></html>"); configUpdateLabel.setText("<html><font color=\"green\">Downloading new version...</font></html>");
logger.info("New version found, downloading..."); logger.info("New version found, downloading...");
try { try {
UpdateUtils.downloadJarAndReplace(updateJarURL); UpdateUtils.downloadJarAndLaunch(updateJarURL);
} catch (IOException e) { } catch (IOException e) {
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null,
"Error while updating: " + e.getMessage(), "Error while updating: " + e.getMessage(),
@ -129,7 +131,7 @@ public class UpdateUtils {
return intVersions; return intVersions;
} }
private static void downloadJarAndReplace(String updateJarURL) private static void downloadJarAndLaunch(String updateJarURL)
throws IOException { throws IOException {
Response response; Response response;
response = Jsoup.connect(updateJarURL) response = Jsoup.connect(updateJarURL)
@ -140,40 +142,96 @@ public class UpdateUtils {
FileOutputStream out = new FileOutputStream(updateFileName); FileOutputStream out = new FileOutputStream(updateFileName);
out.write(response.bodyAsBytes()); out.write(response.bodyAsBytes());
out.close(); out.close();
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}); 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); System.exit(0);
} }
public static void moveUpdatedJar() { public static void moveUpdatedJar() {
File newFile = new File(updateFileName); // Copy the new file (ripme.jar.update) to original location (ripme.jar)
File oldFile = new File(mainFileName); // 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()) { if (!newFile.exists()) {
// Can't update without .update file // Can't update without .update file
return; 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 { try {
oldFile.delete(); logger.info("Updated .jar file '" + newFile + "' exists, overwriting older version at " + oldFile + " ...");
} catch (Exception e) { FileUtils.copyFile(newFile, oldFile);
logger.error("Failed to delete old jar file: " + 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; return;
} }
} }
boolean success = newFile.renameTo(oldFile); // Execute the copied, updated .jar at ripme.jar
if (!success) {
logger.error("Failed to rename file from " + newFile.getAbsolutePath() + " to " + oldFile.getAbsolutePath());
return;
}
try { try {
logger.debug("Executing jar " + oldFile.getName()); String[] command = new String[] {
Runtime.getRuntime().exec(new String[] {"java", "-jar", oldFile.getName()}); "java",
logger.info("Started new version, quitting old version..."); "-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); 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; return;
} }
} }