在Java中创建一个新进程,退出当前进程。

huangapple go评论77阅读模式
英文:

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!

The Error Log

答案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);          //在这里使用正常的退出代码
    }
}

这对我有用,如果您认为这个实现可以改进,我很乐意听取。感谢您的所有支持 在Java中创建一个新进程,退出当前进程。

英文:

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(&quot;java&quot;, &quot;&lt;classname&gt;&quot;);
		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(&quot;Hello World&quot;);
        //exit the process with a code for the SessionManager&#39;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 在Java中创建一个新进程,退出当前进程。

huangapple
  • 本文由 发表于 2020年7月24日 14:25:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/63068015.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定