英文:
Create a new process in Java, exit the current process
问题
在我的代码中,我想要重新启动程序。为此,在Windows中我使用了以下代码:
if(System.getProperty("os.name").contains("Windows"))
{
//For Windows Builds use this
new ProcessBuilder("java", "Launcher").inheritIO().start();
System.exit(0);
}
对于Linux Builds,我使用了以下代码:
else
{
//For Linux/Unix or Mac Builds use this
new ProcessBuilder("/bin/bash", "-c", "java Launcher").inheritIO().start();
}
所以现在,在Windows中的实现工作得很好。它启动了一个新实例并退出了旧实例。但是Linux的实现有点奇怪。我添加了 System.exit(0);
以为它会在创建新进程后立即终止当前进程,但它似乎退出了进程本身。在Linux中,无论如何都无法重新启动程序,尽管在Windows中是可以的。期待您的帮助和反馈!
编辑:[2020年7月28日]
所以我发现新进程已经创建,但IO没有传递到新会话。我稍微调整了一下代码,现在程序创建了新进程,获得了IO控制权,然后在输入命令后退出。
if(System.getProperty("os.name").contains("Windows"))
{
//For Windows Builds use this
new ProcessBuilder("cmd", "/c", "java Launcher").inheritIO().start();
System.exit(0);
}
else
{
//For Linux/Unix or Mac Builds use this
long pid = ProcessHandle.current().pid();
System.out.println(pid);
String a = String.valueOf(pid);
Thread.sleep(10000);
System.out.println(new ProcessBuilder("/bin/bash", "-c", "java Launcher").inheritIO().start());
System.exit(1);
}
如果没有 System.exit(1);
,程序将继续与新创建的进程一起运行,但旧进程仍在后台运行。当我尝试终止旧进程时,两个进程都会被终止。
这是带有上述指定代码的新屏幕截图。
屏幕截图
编辑:[2020年7月29日]
我一直在研究代码为何不起作用的原因。我发现了相同代码的异常,但WSL没有检测到它!
英文:
In my code, I want to restart the program. For this i have used the following code in Windows:
if(System.getProperty("os.name").contains("Windows"))
{
//For Windows Builds use this
new ProcessBuilder("java", "Launcher").inheritIO().start();
System.exit(0);
}
For Linux Builds I used
else
{
//For Linux/Unix or Mac Builds use this
new ProcessBuilder("/bin/bash", "-c" ,"java Launcher").inheritIO().start();
}
So now, the implementation for Windows works just fine. It begins a new instance and exits the old.
But the Linux implementation is kinda a bit odd. I added System.exit(0);
thinking that it will kill the current process right after creating the new one, but it seemed to exit the process itself. I cannot restart the program in anyway in Linux, although it was doable in Windows.
Would appreciate help and feedback!
EDIT: [28-July-2020]
So I did find that the new process is created, but the IO is not inherited to the new session. I tweaked a bit of code and now the program creates the new process, gets IO control and after entering a command, it exits.
if(System.getProperty("os.name").contains("Windows"))
{
//For Windows Builds use this
new ProcessBuilder("cmd", "/c", "java Launcher").inheritIO().start();
System.exit(0);
}
else
{
//For Linux/Unix or Mac Builds use this
long pid = ProcessHandle.current().pid();
System.out.println(pid);
String a=String.valueOf(pid);
Thread.sleep(10000);
System.out.println(new ProcessBuilder("/bin/bash", "-c", "java Launcher").inheritIO().start());
System.exit(1);
}
Without System.exit(1);
the program continues with the newly created process, but with the old process still running in the background. When I try to kill the old process, both the processes are killed.
Here are the new screenshots, with the code specified above.
https://gofile.io/d/MAYLeJ
EDIT: [29-July-2020]
Been working more on why the code is not working. I did get an exception for the same code, which WSL didnt detect!
答案1
得分: 0
更新:我找到了正确的答案,可能有点复杂,但我会尽量简化。
在这个过程中,我们需要两个单独的类:一个用于监控子进程的类,一个是主进程的类。
为了简单起见,我将监控类命名为 SessionManager
,主类命名为 mainClass
。
在 SessionManager
类中,我实现了以下代码。
try
{
//一个无限循环,用于监视和启动新进程
while(true)
{
//创建进程并监听子进程生成的退出代码。
ProcessBuilder session_monitor=new ProcessBuilder("java", "<classname>");
Process process_monitor= session_monitor.inheritIO().start();
//在继续之前等待子进程结束
process_monitor.waitFor();
switch(process_monitor.exitValue())
{
//在这里实现逻辑
case 0: //做些什么
break;
case 1: //做些什么
break;
}
}
}
catch(Exception E)
{
E.printStackTrace();
}
而在 mainClass
程序中,我们将有一个主方法来启动进程运行。
class mainClass
{
public static void main(String[] args)
{
System.out.println("Hello World");
//使用一个代码来退出进程,以使 SessionManager 的逻辑生效
System.exit(0); //在这里使用正常的退出代码
}
}
这对我有用,如果您认为这个实现可以改进,我很乐意听取。感谢您的所有支持
英文:
Update: I did find the right answer and it might be a bit complex, but I shall try to make it as simple as possible.
In this, we will require 2 separate classes: 1 class to monitor the child process, 1 class which is the main process.
For the sake of simplicity, I shall name the monitoring class as SessionManager
and the main class as mainClass
In the SessionManager class, I've implemented the following code.
try
{
//A loop which will run infinitely to montior and start new processes
while(true)
{
//Create the process and listen to the exit code generated by the child process spawned.
ProcessBuilder session_monitor=new ProcessBuilder("java", "<classname>");
Process process_monitor= session_monitor.inheritIO().start();
//wait for the child process to end before proceeding
process_monitor.waitFor();
switch(process_monitor.exitValue())
{
//Implement the logic here
case 0: //do something
break;
case 1: //do something
break;
}
}
}
catch(Exception E)
{
E.printStackTrace();
}
And in the mainClass
program, we shall have a main method to start the process running.
class mainClass
{
public static void main(String[] args)
{
System.out.println("Hello World");
//exit the process with a code for the SessionManager's logic to work
System.exit(0); //Using a normal exit code here
}
}
This has worked for me, and if you think this implementation can be improved, I'd love to hear it. Thank you for all your support
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论