I am trying to achieve the automatic update for my java web-start applicaiton. Logic: I am fetching the jnlp file from the server and comparing the timestamp with the current one. if there is difference then download the latest file and restart the application with javaws command. Now I have two problems. 1. I am not able to fetch the local jnlp file (because the location for jnlp file is different for different operating system as mentioned here 2. I am not able to find a graceful way to restart the application after killing the current running application. I would appreciate if there is any other graceful solution available. Thanks
My code:
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import javax.swing.JOptionPane;
import org.apache.log4j.Logger;
import com.ibm.nzna.projects.qit.app.PropertySystem;
/**
* QitUpdater . java
*
* @Info Checks for updates for the JWS Application
*
* This program will try to use a given URL to connect online to check for
* a newer version of the jnlpFile. The program then compares the last
* modified dates of the local copy and the URL copy, and notifies the
* user if the URL copy is newer, via a Dialog box popup. The newer
* version can then, be downloaded and installed using JWS.
*
* @Warnings If the server containing QIT changes its directory or location then
* the program will error out every time since the URL link is
* hard-coded.
*
* @author Ashish Tyagi
* @version 4/22/2013
*
*/
public abstract class QitUpdater {
// constant which hold the location of property file and server location
public final static String jnlpFile = PropertySystem.getString(PropertySystem.PROPERTY_JNLP_FILE);
public final static String fileDirectoryURL = PropertySystem.getString(PropertySystem.PROPERTY_JNLP_SERVER);
static Logger logger = Logger.getLogger(QitUpdater.class.getName());
// private variables
private static HttpURLConnection huc;
private static File oldFile = null;
private static long localDate = 0;
private static long remoteDate = 0;
public static void checkUpdates(boolean displayErrors,boolean displayIsUpToDate,boolean autoRunner){
logger.info("value of jnlp file: "+fileDirectoryURL+"/"+jnlpFile);
if(jnlpFile !=null && fileDirectoryURL != null)
checkForUpdates(displayErrors, displayIsUpToDate, autoRunner);
}
/**
* Starts a new task to check for QIT updates.
*
* If there is no connection or the program is up to date, then this method
* returns normally. Otherwise, it will exit the old program and execute the
* newer QIT program.
*
* @param displayErrors
* will show all error messages in popups, if any occur. This is
* recommended to be false on boostrapping, so the 'offline user'
* is not annoyed.
*
* @param displayIsUpToDate
* will show a popup letting the user know if their current
* version of QIT is up to date, if they have the most up to date
* version. Otherwise, it will ignore the popup.
*
* @param autoRunNewer
* will automatically execute the newer JNLP file, if it is found
* or downloaded. This is recommended to be false if this method
* is being called from within a user action, like a button
* press. If it is set to false, a dialog will ask the user to
* restart QIT in order to finish updating the program, if an
* update was found.
*/
public static void checkForUpdates(boolean displayErrors,
boolean displayIsUpToDate, boolean autoRunNewer) {
// Try to find a similarly named file
// in the current local directory
oldFile = new File(jnlpFile);
if (oldFile.exists()) // find the JNLP file
{
// grab the local last modified date to compare
localDate = oldFile.lastModified();
}
// Try to access the base URL
int code = 404;
try {
URL u = new URL(fileDirectoryURL);
huc = (HttpURLConnection) u.openConnection();
huc.setRequestMethod("GET");
huc.connect();
code = huc.getResponseCode();
} catch (MalformedURLException e) {
if (displayErrors)
printError("Error: Could not check for updates.\nMalformedURLException: "
+ e.getMessage()
+ "\n\nClick OK to continue using QIT.");
return;
} catch (IOException e) {
if (displayErrors)
printError("Error: Could not check for updates.\nIOException: "
+ e.getMessage()
+ "\n\nClick OK to continue using QIT.");
return;
}
if (code == 200) {
// 200 is a valid connection
// scan URL for versions
try {
StringBuilder sb = new StringBuilder();
sb.append(fileDirectoryURL).append("/").append(jnlpFile);
URL u = new URL(sb.toString());
huc = (HttpURLConnection) u.openConnection();
huc.setRequestMethod("GET");
huc.connect();
// grab the last modified date
remoteDate = huc.getLastModified();
} catch (MalformedURLException e) {
if (displayErrors)
printError("Error: Failed to download.\n\n"
+ e.getMessage()
+ "\n\nClick OK to continue using QIT.");
return;
} catch (IOException e) {
if (displayErrors)
printError("Error: Failed to download.\n\n"
+ e.getMessage()
+ "\n\nClick OK to continue using QIT.");
return;
}
// compare last modified dates of JNLP files
if (remoteDate != localDate) {
// found a newer version of JNLP
// ask to download
if (0 == printQuestion("An updated version of QIT is available.\n\nLast updated:\n"
+ new Date(remoteDate).toString()
+ "\n\nDo you want to download and install it?")) {
// download and install
try {
downloadUrlFile(jnlpFile, fileDirectoryURL + "/"
+ jnlpFile);
oldFile.setLastModified(remoteDate);
// set the date to the date on the server
if (autoRunNewer) {
// run the JNLP file
try {
Runtime.getRuntime()
.exec("javaws "+jnlpFile);
System.exit(0);// quit this version of QIT
} catch (IOException e) {
if (displayErrors)
printError("Error:\n"
+ e.getMessage()
+ "\n\nClick OK to continue using QIT.");
}
} else
printInfo("In order to finish installing the\nupdate, QIT needs to be restarted.");
} catch (Exception e) {
if (displayErrors)
printError("Error: Failed to download " + jnlpFile
+ ".\n\n" + e.getMessage()
+ "\n\nClick OK to continue using QIT.");
}
}
} else {
// modified dates are the same
// try to launch the current JNLP
if(oldFile.exists())
{
// run the JNLP file
try {
Runtime.getRuntime()
.exec("javaws "+jnlpFile);
System.exit(0);// quit this version of QIT
} catch (IOException e) {
if (displayErrors)
printError("Error:\n"
+ e.getMessage()
+ "\n\nClick OK to continue using QIT.");
}
}
// up to date
if (displayIsUpToDate)
printInfo("QIT is up to date.\n\nLast update was:\n"
+ (new Date(localDate).toString())
+ "\n\nClick OK to continue.");
}
}
return;
}
/**
* Downloads the urlString to the filename at the current directory.
*
* @param filename
* @param urlString
* @throws MalformedURLException
* @throws IOException
*/
public static void downloadUrlFile(String filename, String urlString)
throws MalformedURLException, IOException {
BufferedInputStream in = null;
FileOutputStream fout = null;
try {
URL url = new URL(urlString);
huc = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(url.openStream());
fout = new FileOutputStream(filename);
byte data[] = new byte[1024];
int count;
while ((count = in.read(data, 0, 1024)) != -1) {
fout.write(data, 0, count);
}
} finally {
if (in != null)
in.close();
if (fout != null)
fout.close();
}
}
/**
* Display an error
*
* @param e
*/
private static void printError(String e) {
JOptionPane.showMessageDialog(null, e, "Error",
JOptionPane.ERROR_MESSAGE);
}
/**
* Display some information
*
* @param s
*/
private static void printInfo(String s) {
JOptionPane.showMessageDialog(null, s, "Information",
JOptionPane.INFORMATION_MESSAGE);
}
/**
* Prompt a Yes/No Question
*
* @param String
* q
* @return int 0 means YES, 1 means NO, -1 means they clicked "X" close
*/
private static int printQuestion(String q) {
return JOptionPane.showConfirmDialog(null, q, "Question",
JOptionPane.YES_NO_OPTION);
}
}