2011-01-10 54 views
3

我有一个相当大的java程序,我们想让它使用户可以退出应用程序并以另一个用户身份登录。要做到这一点,我们想关闭应用程序并重新启动它,以便向用户显示登录对话框。问题是,该应用程序相当大,写得不好。它有很多静态变量可以保存某种状态信息。理想情况下,我想重写应用程序以处理这些可以全部清除的情况,但实际上我们需要尽快提供此功能。如何从java内重新启动java程序?

我在想什么最简单的就是停下应用程序并开始一个新的虚拟机。然而,在关闭当前应用程序的同时停止并应用并启动相同的应用程序似乎令人惊讶地困难。有没有人有这样的经验?

编辑:我们正在追求使用Runtime.exec来再次调用同一个应用程序,但exec()想阻止,所以我们必须跳过箍环让它在每个平台(Windows,Mac,Linux)上工作。我更喜欢独立于平台的方式。

+0

可能重复[重新启动Java应用程序。](http://stackoverflow.com/questions/4159802/restart-a-java-application) – 2011-01-10 18:01:20

+0

该问题有一个答案使用`ProcessBuilder`,这是建议在`Runtime.exex(cmdarray,envp,dir)`的文档。 “ProcessBuilder.start()现在是使用修改后的环境启动进程的首选方式。” – 2011-01-10 18:13:45

+0

这应该是“Runtime.exec(...)”(不是“exex”)。 – 2011-01-15 01:30:59

回答

2

如果您可以修改代码,也许可以退出程序并使用exec()方法使用Runtime类(java.lang.Runtime)再次启动相同的程序(使用相同的参数?)。

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

编辑:也就是说,你第一次运行新的进程,然后退出程序。另一种方式当然会更困难或不可能(?)。 :)

1

如果您真的想停止JVM并重新启动它,那么您必须编写一些包装脚本(shell脚本或批处理文件,具体取决于您的操作系统)。您可以使用来自System.exit()的特殊返回码来指示应该重新启动应用程序。

而这可能是最好的办法。你可以玩一些类加载器技巧,在其中创建一个自定义类加载器来加载应用程序的类。但是,有很多方法会出错:例如,应用程序代码可能会在某个隐藏位置调用System.exit(),或者它可能包含保留引导类加载器加载的类中的内部引用的代码。

0

静态成员与classloader:classname相关联。您可以创建自己的类加载器并通过它实例化您的应用程序。然后,当你想重新启动时,扔掉classloader并创建一个新类。这就是像JBoss这样的应用程序引擎能够即时重新加载应用程序的方式。

0

您可以使用RuntimeProcessBuilder重新启动您的应用程序,但您可能必须稍微修改您的应用程序,因为我非常确定您无法从JVM中检索Java可执行文件完整路径。

我建议你实现一个启动器(作为一个可执行文件或脚本)并使用java返回代码来知道是否需要退出或者是否需要退出或重新启动。