2

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);
    }
}
4

1 回答 1

2

我正在尝试为我的 java web-start 应用程序实现自动更新

使用DownloadServiceJNLP API。

DownloadService服务允许应用程序控制它自己的资源如何被缓存,确定它的哪些资源当前被缓存,强制资源被缓存,以及从缓存中移除资源。JNLP 客户端负责提供此服务的特定实现。

于 2013-05-08T17:01:00.917 回答