为了清晰起见,重新写这个是为了清楚:
我想要做的是为已经以(可执行的)jar形式制作的程序创建一个bootstrap加载器。这个引导程序在运行时会有三个简单的目标:
将目标程序的本地xml文件与托管在服务器上的文件进行比较(以确保它们是相同的版本)
如果版本不同,在线版本较新,请下载较新版本。
重写xml文件以反映此更改。
执行第二个jar文件(就像启动可执行文件一样启动它)。
我遇到的问题是第4步。我发现自己很难找到一种可靠的方法从我的引导程序中启动一个jar,尽管你看过UrlClassLoader和其他库。
由于一些外部问题,JNLP / Web-start不适用于此案例。
TL; DR:我需要找到一种从jar中下载/启动jar的方法,以便在运行bootstrap时更新程序。
谢谢!
答案 0 :(得分:0)
调用Runtime.getRuntime()。EXEC()
如果您的MyApp.jar有任何输出,那么这里有一些陷阱。
检查文档以了解如何正确使用exec的详细信息...
http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html
看到这篇关于一些陷阱的SO帖子......
答案 1 :(得分:0)
当您说'执行新jar'时,您的意思是启动独立应用程序吗? 一种可能性是简单地从Updater.jar引导逻辑执行一个新的Java进程,然后退出自己。
答案 2 :(得分:0)
换句话说,您希望实现可自我更新的应用程序。这是可能的,甚至不是那么困难。
您的程序应设计为2个部分。加载器(和更新程序)和业务逻辑。 Loader应该使用单独的类加载器启动业务逻辑。您可以使用UrlClassLoader
。加载程序将转到在线服务并检查版本。如果需要,它将创建URLConnection
,下载新的jar
并将其存储在filesytem中的某个位置(例如,在用户主目录中)。然后它将使用已经提到的类加载器运行业务逻辑,该加载器从刚刚下载的jar文件加载类。
这实际上模仿了JNLP的行为。
答案 3 :(得分: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>
Sidenote-我没有自动更新version.xml,你可以编辑那里的数字来匹配,或者只是拉一下你检查的数字来替换它。