3

我已经为这个问题苦苦挣扎了一段时间,但我似乎无法解决它。我已经尝试过不同的方法(Runtime.exec()、ProcessBuiler),但似乎都没有。

这是我的问题。我有一台一直开着的笔记本电脑。这台笔记本电脑运行一个通过 USB 连接到 arduino 的 java 工具来打开和关闭房子里的灯。我自己创建了这个程序,因此我也在做一些定期维护工作。最近我添加了一个按钮来从我的 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“”:错误=2,在 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) 在 home.automation.executor.webserver.HTTPGenerator.getHTTPPage(HTTPGenerator.java:58) 在 home.automation.executor .webserver.HTTPRequestHandler.run(HTTPRequestHandler.java:160) 原因:java.io.IOException: error=2, java.lang 中没有这样的文件或目录。UNIXProcess.forkAndExec(Native Method) at java.lang.UNIXProcess.(UNIXProcess.java:53) at java.lang.ProcessImpl.start(ProcessImpl.java:91) at java.lang.ProcessBuilder.start(ProcessBuilder.java:453 ) ... 5 更多

4

2 回答 2

5

问题是这样的:

String startupCommand = "java -jar \"" + this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath().replace("%20", " ") + "\"";

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

这意味着 Jav 将查找名为 java -jar ...stuff with spaces.... 但是您想要的是,Java 会查找名为的命令java并为该命令提供几个参数。

你应该使用

/*...*/ builder.command("java", "-jar", jarLocation) /*...*/
于 2012-07-21T16:36:12.540 回答
1

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

于 2012-07-21T16:31:41.560 回答