Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I whipped up some code recently, but due to the way a process is created, this can only be run on Windows, and it doesn't work quite how I want it to either. I would love to get some advice from a more veteran coder on what could be improved and what should be added.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import org.w3c.dom.Document;

@SuppressWarnings("serial")
public class updater extends JFrame {
    static JProgressBar progressBar = new JProgressBar();
    static JLabel progressLabel = new JLabel();
    static double version;
    static String programName;
    static updater ex = new updater();
    Thread t;

    public updater() {
        setTitle("NOC - Updater");
        setSize(600, 130);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(null);

        progressLabel.setBounds(110, 10, 500, 25);

        progressBar.setBounds(60, 40, 500, 40);

        add(progressLabel);
        add(progressBar);
    }

    public static void main(String[] args) throws IOException,InterruptedException {
        try {
            //Create HttpClient and pull remote version.xml into an inputstream
            final DefaultHttpClient httpclient = ClientMaker();
            HttpGet get = new HttpGet("http://myServer:8080/Updater-test/Version.xml");
            HttpResponse response = httpclient.execute(get);
            final InputStream in = response.getEntity().getContent();

            //Create Xml Parsers
            DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = domFactory.newDocumentBuilder();
            Document doc = builder.parse(in);

            // Get Remote Version Number
            XPathFactory factory = XPathFactory.newInstance();
            XPath xpath = factory.newXPath();
            XPathExpression expr = xpath.compile("//version/number/text()");
            String result = (String) expr.evaluate(doc, XPathConstants.STRING);
            //System.out.println(result);
            version = Double.parseDouble(result);

            // Get Program Name
            expr = xpath.compile("//version/program/text()");
            String result2 = (String) expr.evaluate(doc, XPathConstants.STRING);
            //System.out.println(result2);
            programName = result2;

            //Thread to handle SWT and downloading
            Thread t = new Thread() {
                public void run() {
                    try {
                        SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                ex = new updater();
                                ex.setVisible(true);
                            }
                        });
                        //Download jar + xml file
                        jarFileDownload(httpclient);
                        xmlFileDownload(httpclient);

                        //Once done downloading hide swing stuff.
                        ex.setVisible(false);

                        //Run file (windows only)
                        Process p = Runtime.getRuntime().exec("cmd.exe /C  javaw -jar "+ System.getProperty("user.dir")+ "\\MyOutput.jar");
                        //Wait for it to finish running
                        p.waitFor();
                        //Kill any open file hooks
                        p.destroy();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                };
            };

            // Get Local Version Number
            File f = new File(System.getProperty("user.dir") + "\\Version.xml");

            //If Version.xml doesn't exist locally
            if (!f.exists()) {
                t.start();
                //Run file (windows only)
                Process p = Runtime.getRuntime().exec("cmd.exe /C  javaw -jar "+ System.getProperty("user.dir")+ "\\MyOutput.jar");
                //Wait for it to finish running
                p.waitFor();
                //Kill any open file hooks
                p.destroy();
                System.exit(0);
            }

            //If it does exist, pull it in and check its version number
            InputStream in2 = new FileInputStream(f);
            doc = builder.parse(in2);
            expr = xpath.compile("//version/number/text()"); //Parse the number out of it.
            String result3 = (String) expr.evaluate(doc, XPathConstants.STRING);
            //System.out.println(result3);
            in2.close();

            //If the file version is out of date
            if (Double.parseDouble(result3) < Double.parseDouble(result)) {
                System.out.println(Thread.currentThread().getState());
                t.start();
                in.close();
            }

        //multicatch for stuff that shouldn't happen ever.
        } catch (FileNotFoundException fnf) {
            System.out.println("FNF: " + fnf.getMessage());
            fnf.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // Downloads the xml file
    public static void xmlFileDownload(HttpClient httpClient)throws ClientProtocolException, IOException {
        HttpGet get2 = new HttpGet("http://myServer:8080/Updater-test/Version.xml"); // XML FILE LOCATION
        HttpResponse response2 = httpClient.execute(get2);
        Header[] headers = response2.getHeaders("content-length");
        int contentLength = Integer.parseInt(headers[0].getValue());
        //System.out.println("The Length of the content is: " + contentLength);

        //Make the progress bar happen
        progressBar.setValue(0);
        progressBar.setMinimum(0);
        progressBar.setMaximum(contentLength);
        InputStream in3 = response2.getEntity().getContent();
        File xmlFile = new File("Version.xml");
        OutputStream fos = new FileOutputStream(xmlFile);
        byte buf[] = new byte[1024];
        int len = 0, total = 0;
        while ((len = in3.read(buf)) > 0) {
            fos.write(buf, 0, len);
            total += len;
            progressLabel.setText("Downloading version: " + version + " of "+ programName + " : " + total + " / " + contentLength+ "  Bytes downloaded");
            progressBar.setValue(total);
        }

    }

    // Downloads the JarFile
    public static void jarFileDownload(HttpClient httpClient)throws ClientProtocolException, IOException {
        HttpGet get2 = new HttpGet("http://myServer:8080/Updater-test/MyProgram.jar");  //LOCATION OF THE JAR FILE
        HttpResponse response2 = httpClient.execute(get2);
        Header[] headers = response2.getHeaders("content-length");
        int contentLength = Integer.parseInt(headers[0].getValue());
        //System.out.println("The Length of the content is: " + contentLength);


        // Change the progressbar so that this works.
        progressBar.setValue(0);
        progressBar.setMinimum(0);
        progressBar.setMaximum(contentLength);
        InputStream in3 = response2.getEntity().getContent();
        File jarFile = new File("MyOutput.jar");
        OutputStream fos = new FileOutputStream(jarFile);
        byte buf[] = new byte[1024];
        int len = 0, total = 0;
        while ((len = in3.read(buf)) > 0) {
            fos.write(buf, 0, len);
            total += len;
            progressLabel.setText("Downloading version: " + version + " of "+ programName + " : " + total + " / " + contentLength+ "  Bytes downloaded");
            progressBar.setValue(total);
        }
    }

    public static DefaultHttpClient ClientMaker() {
        int connectiontimeout = 30000; // 1 second int sockettimeout = 1000;
        HttpParams httpparameters = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(httpparameters,connectiontimeout);
        HttpConnectionParams.setSoTimeout(httpparameters, connectiontimeout);
        DefaultHttpClient httpclient = new DefaultHttpClient(httpparameters);
        return httpclient;
    }

}
share|improve this question

closed as off-topic by Simon André Forsberg, palacsint, syb0rg, Jamal Feb 9 at 3:15

  • This question does not appear to be a code review request within the scope defined in the help center.
If this question can be reworded to fit the rules in the help center, please edit the question.

    
Well, this is rather complex. First things I see ( if I get it correct) is that you mix up with the event dispatch thread. Than, the download and execute looks unusual to me, but I do not know the requirements, so I do not know a better solution. Sadly, I can not test around with it because I can not install 3. lib here, sorry. To get it cross platform, you should either code for every required platform or find a more general way which fits your requirements. –  tb- Nov 23 '12 at 18:31
    
If you want to test around with it, you can make it download any executable jar. version.xml is just a file that is very simple: <?xml version="1.0" encoding="ISO-8859-1"?> <version> <number>1.1</number> <program>Ares</program> </version> That was the xml file I was using. –  Damien.Bell Nov 24 '12 at 13:08
3  
This question appears to be off-topic because it is more about solving a problem with multi-platform than reviewing code. Also, as stated in the question the code doesn't work "quite" as intended. –  Simon André Forsberg Nov 18 '13 at 21:37
add comment

Browse other questions tagged or ask your own question.