在Linux上运行Java进程

3

我已经尝试了不同的方法(Runtime.exec(),ProcessBuiler)来解决这个问题,但似乎都没有成功。

我的问题是这样的。我有一台笔记本电脑,它始终处于开启状态。这台笔记本运行一个Java工具,通过USB连接到Arduino,以打开和关闭房子里的灯。我自己编写了这个程序,因此我也会进行一些常规维护工作。最近,我在我的HTML界面中添加了一个按钮,用于重新启动程序(以防我有更新,或者出于其他原因需要重新启动程序,或者我决定在不久的将来实现自动更新)。

这个想法是从第一个实例开始启动第二个应用程序实例,然后System.exit(0)第一个实例。

由于某种原因,我无法启动第二个应用程序实例。以下是一些代码。

public void shutdown(boolean restart) {
        if (this.serial != null) {
            this.serial.disconnect();
        }

        if (restart) {
            System.out.println(this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
            String startupCommand = "java -jar \"" + this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath().replace("%20", " ") + "\"";
            ProcessBuilder builder = new ProcessBuilder();

//            String[] command = new String[1];
//            command[0] = "-jar \"" + (System.getProperty("user.dir") + "/Home_Automation_Executor.jar") + "\"";
            try {
//                //System.out.println("Restarting Home Automation with command: " + command[0]);
//                System.out.println("Restarting Home Automation with command: " + startupCommand);
//                Runtime.getRuntime().exec("bash");
//                Process proc = Runtime.getRuntime().exec(startupCommand);
                Process proc = builder.command(startupCommand).start();
                InputStream stderr = proc.getErrorStream();
                InputStreamReader isr = new InputStreamReader(stderr);
                BufferedReader br = new BufferedReader(isr);
                String line = null;
                System.out.println("<ERROR>");
                while ((line = br.readLine()) != null) {
                    System.out.println(line);
                }
                System.out.println("</ERROR>");
                int exitVal = 0;
                try {
                    exitVal = proc.waitFor();
                } catch (InterruptedException ex) {
                    Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
                }
                System.out.println("Process exitValue: " + exitVal);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        System.out.println("Terminating Home Automation");
        System.exit(0);
    }

java.io.IOException:无法运行程序“java -jar”/Users/NightWalker/Dropbox/Development/Source Code/Java/NightWare Tools/Home Automation/Home Automation Executor/dist/Home_Automation_Executor.jar":error=2,没有这样的文件或目录。
在java.lang.ProcessBuilder.start(ProcessBuilder.java:460)处出现错误。 在home.automation.executor.Engine.shutdown(Engine.java:186)处关闭引擎。 在home.automation.executor.webserver.HTTPGenerator._handleActionCommand(HTTPGenerator.java:190)处理动作命令。 在home.automation.executor.webserver.HTTPGenerator._generateHTTPPage(HTTPGenerator.java:165)生成HTTP页面。 在home.automation.executor.webserver.HTTPGenerator.getHTTPPage(HTTPGenerator.java:58)获取HTTP页面。 在home.automation.executor.webserver.HTTPRequestHandler.run(HTTPRequestHandler.java:160)运行时发生错误。 导致原因是:java.io.IOException:error=2,没有这样的文件或目录。 在java.lang.UNIXProcess.forkAndExec(Native Method)处出现错误。 在java.lang.UNIXProcess.(UNIXProcess.java:53)处发生错误。 在java.lang.ProcessImpl.start(ProcessImpl.java:91)处开始进程。 在java.lang.ProcessBuilder.start(ProcessBuilder.java:453)处开始进程。

那个“某些原因”实际上是什么? - A.H.
2个回答

5
问题是这样的:
String startupCommand = "java -jar \"" + this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath().replace("%20", " ") + "\"";

/* more stuff */ builder.command(startupCommand);

这意味着Java将寻找一个名为java -jar ...stuff with spaces...的命令。但是你想要的是,Java查找名为java的命令,并给该命令传递几个参数。
你应该使用:
/*...*/ builder.command("java", "-jar", jarLocation) /*...*/

完全正确,+1。但是使用 Runtime.getRuntime().exec(startupCommand) 应该可以工作。 - Stephan
@Stephan:那行不通,因为该版本的exec将在空格上分割命令,并且错误消息中的jar路径包含空格,而TO希望它能够正常工作(replace(...))。 - A.H.

1

由于这是另一个Java程序,您可能希望考虑在同一个进程中运行它,因为如果两个程序在同一个进程中运行,它们之间的通信会更加容易。您尝试过在程序外运行该命令吗?它能工作吗? jar包中的meta-inf.mf文件包含什么?可能是该文件中的类路径不是相对路径,因此无法找到任何依赖的jar包。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接