更新java桌面应用程序
我正在尝试开发一个模块,可以更新我正在运行的Java桌面应用程序。 问题是,我必须用另一个jar替换实际运行的jar,同时显示一个图像和一个进度条以及更新过程的剩余时间 我考虑的一个解决方案是,我可以在我的主jar中放置一个jar,在启动更新过程时,提取第二个jar,它将显示图像和进程栏,还将用一个新的主jar替换旧的主jar。 我的问题是,这是否可能,我如何才能做到。 我在java和java打包方面没有很多经验,因此如果您有任何示例或链接,这将对我有很大帮助 多谢各位。更新java桌面应用程序,java,desktop-application,executable-jar,auto-update,Java,Desktop Application,Executable Jar,Auto Update,我正在尝试开发一个模块,可以更新我正在运行的Java桌面应用程序。 问题是,我必须用另一个jar替换实际运行的jar,同时显示一个图像和一个进度条以及更新过程的剩余时间 我考虑的一个解决方案是,我可以在我的主jar中放置一个jar,在启动更新过程时,提取第二个jar,它将显示图像和进程栏,还将用一个新的主jar替换旧的主jar。 我的问题是,这是否可能,我如何才能做到。 我在java和java打包方面没有很多经验,因此如果您有任何示例或链接,这将对我有很大帮助 多谢各位。 R.您可以拥有一个初学
R.您可以拥有一个初学者jar,用于检查更新并从主jar启动应用程序 它将显示start徽标,一个标准java可以在启动时显示的图像。 start0er还可以用另一种界面语言重新启动应用程序
package starter;
...
public class StarterApp {
public static void main(String[] args) {
String workDir = System.getProperty("user.dir");
Path mainJar = Paths.get(workDir + "...");
Path nextMainJar = Paths.get(workDir + "...");
if (Files.exists(nextMainJar)) {
Files.copy(nextMainJar, mainJar, StandardCopyAction.REPLACE_EXISTING);
}
URLClassLoader classLoader = new URLClassLoader(new URL[] {mainJar.toURL()});
Class<?> appClass = classLoader.find("mainjar.MainApp");
... instantiate the app
}
包装启动器;
...
公共类应用程序{
公共静态void main(字符串[]args){
字符串workDir=System.getProperty(“user.dir”);
Path mainJar=Path.get(workDir+“…”);
Path nextMainJar=Path.get(workDir+“…”);
if(Files.exists(nextMainJar)){
复制(nextMainJar、mainJar、StandardCopyAction.REPLACE_现有);
}
URLClassLoader classLoader=新的URLClassLoader(新的URL[]{mainJar.toURL()});
类appClass=classLoader.find(“mainjar.MainApp”);
…实例化应用程序
}
正如您所看到的,主jar不能过早加载,可能不完全在类路径上,因此需要使用单独的类加载器。对于starter应用程序的类路径上的主jar,也可以使用class.forName(“mainjar.MainApp”)进行加载
。可以在META-INF/MANIFEST.MF中指定类路径
secundary jar可以驻留在lib/目录中
对于那些想要更多模块化、面向服务、可更新应用程序的读者,可以制作一个OSGi应用程序,一个捆绑包(=JAR)的容器,提供可交换的服务和终身控制。当按下更新按钮时运行此代码
if(Desktop.isDesktopSupported()){
try {
Desktop.getDesktop().open(new File("update.jar"));
System.exit(0);
} catch (IOException ex) {
}
}
这将打开update.jar并关闭main.jar
if(isUpdateVersionAvailable()) { //first check update from database
try{
Thread.sleep(5000);
} catch(Exception e){
e.printStackTrace();
}
if(copyMainJarFileFromServer()){ //copy newMain.jar from server and paste
new File("main.jar").delete();
rename(new File("newMain.jar"));
}
}
boolean isUpdateVersionAvailable() {
//todo
}
boolean copyMainJarFileFromServer() {
//todo
}
void rename(File file){
file.renameTo(new File("main.jar"));
}
请务必让我们知道您是否成功,您是否确定在不停止应用程序的情况下更新“主UI”是有意义的?我曾经创建了一个支持多个插件的大型应用程序;每个插件都可以“动态”更新。但为了更新“主UI”…您无论如何都必须“停止”(因为你将不得不放弃用来加载JAR内容的类加载器)。意思是:用户无论如何都会经历一次“中断”;那么为什么要卸载一个JAR,加载一个新的(带有进度条)?停止应用程序并拥有一个独立的“升级应用程序”会容易得多。你可以考虑一些“启动器”-启动主应用程序的应用程序。启动器可以在启动主应用程序之前更新主应用程序。其想法是,必须从主jar中提取内部jar,主jar将停止运行,并且内部jar将显示进度条和图像。此外,内部jar将替换主jar(从主jar上的另一个位置复制一个新的jar),然后它将启动新的主jar并退出。很难实现。我必须在主jar运行时提取内部jar。我如何才能做到这一点?您需要等待update.jar,直到终止main.jar