3

在我赏金之前重写它以清楚起见:

我想要做的是为已经以(可执行)jar 形式制作的程序制作引导加载程序。这个引导程序在运行时将有三个简单的目标:

  1. 将目标程序的本地 xml 文件与服务器上托管的文件进行比较(以确保它们是相同的版本)

  2. 如果不是同一个版本,并且在线版本较新,请下载较新版本。

  3. 重新编写 xml 文件以反映此更改。

  4. 执行第二个 jar 文件(就像启动可执行文件一样启动它)。

我遇到的问题是第 4 步。尽管查看了 UrlClassLoader 和其他库,但我发现自己很难找到一种可靠的方法来从我的引导程序中启动 jar。

由于一些外部问题,JNLP / Web-start 不是这种情况下的选项。

TL;DR:我需要找到一种从 jar 中下载/启动 jar 的方法,以便在运行引导程序时更新程序。

谢谢!

4

4 回答 4

0

Runtime.getRuntime().exec()

如果您的 MyApp.jar 有任何输出,这里有一些陷阱。

查看文档以获取有关如何正确使用 exec 的详细信息...

http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html

并看到这个关于一些陷阱的SO帖子......

Java 运行时.exec()

于 2012-11-12T21:29:22.547 回答
0

当您说“执行新 jar”时,您的意思是启动一个独立的应用程序吗?一种可能性是简单地从 Updater.jar 引导逻辑执行一个新的 Java 进程,然后退出本身。

于 2012-11-12T21:30:16.413 回答
0

换句话说,您想要实现可自我更新的应用程序。这是可能的,甚至没有那么困难。

您的程序应设计为包含 2 个部分。加载器(和更新器)和业务逻辑。加载器应该使用单独的类加载器启动业务逻辑。您可以使用UrlClassLoader. 加载程序将转到在线服务并检查版本。如果需要,它将创建URLConnection、下载新文件jar并将其存储在文件系统中的某个位置(例如,在用户主目录中)。然后它将使用已经提到的类加载器运行业务逻辑,该类加载器从刚刚下载的 jar 文件加载类。

这实际上模仿了 JNLP 行为。

于 2012-11-12T21:32:22.107 回答
0

我讨厌不得不回答我自己的问题,但在这种情况下,我觉得需要完成......

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

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.HttpResponse;
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;


public class updater {
public static void main(String[] args) throws IOException {
    try{
        DefaultHttpClient httpclient = ClientMaker();
        HttpGet get = new HttpGet("http://encorpops04:8080/Updater-test/Version.xml");
        HttpResponse response = httpclient.execute(get);
        InputStream in = response.getEntity().getContent();

        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = domFactory.newDocumentBuilder();
        Document doc = builder.parse(in);

        //Parse the Xml.
        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);

        File f = new File(System.getProperty("user.dir")+ "\\Version.xml");
        in = new FileInputStream(f) ;
        doc = builder.parse(in);
        expr=xpath.compile("//version/number/text()");
        String result2 = (String) expr.evaluate(doc, XPathConstants.STRING);
        System.out.println(result2);


        if(Double.parseDouble(result2) < Double.parseDouble(result)){
            HttpGet get2 = new HttpGet("http://encorpops04:8080/Updater-test/MyOutput.jar"); 
            HttpResponse response2 = httpclient.execute(get2);
            InputStream in2 = response2.getEntity().getContent();
            File f2 = new File("MyOutput.jar");
            OutputStream fos = new FileOutputStream(f2);
            byte buf[] = new byte[1024];
            int len;
            while ((len = in2.read(buf)) > 0) {
                fos.write(buf, 0, len);
            }
            fos.close();
            in.close();
        }
        System.out.println("cmd.exe /C  javaw -jar"  +System.getProperty("user.dir") + "\\MyOutput.jar");
        Process p = Runtime.getRuntime().exec("cmd.exe /C  javaw -jar "  +System.getProperty("user.dir") + "\\MyOutput.jar");
        p.waitFor();
        p.destroy();
    }catch(Exception e){ e.printStackTrace(); }


}

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

}

Version.xml 看起来像这样:

<?xml version="1.0" encoding="ISO-8859-1"?>
<version>
    <number>1.0</number>
</version>

旁注-我没有自动更新 version.xml,您可以编辑其中的数字以匹配,或者只需拉出您检查的数字来替换它。

于 2012-11-17T17:20:41.703 回答