Процесс выполнения Java в Linux

Я уже некоторое время борюсь с этой проблемой, и я не могу ее исправить. Я уже пробовал разные подходы (Runtime.exec(), ProcessBuiler), но ни один из них не работает.

Это моя проблема. У меня есть ноутбук, который всегда включен. Этот ноутбук запускает инструмент Java, подключенный к Arduino через USB, для включения и выключения света в доме. я создал эту программу сам, поэтому я также регулярно занимаюсь ее обслуживанием. Недавно я добавил кнопку для перезапуска программы из моего 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) в доме. .webserver.HTTPRequestHandler.run(HTTPRequestHandler.java:160) Причина: java.io.IOException: error=2, Нет такого файла или каталога в java.lang.UNIXProcess.forkAndExec(собственный метод) в java.lang.UNIXProcess. (UNIXProcess.java:53) в java.lang.ProcessImpl.start(ProcessImpl.java:91) в java.lang.Pr ocessBuilder.start(ProcessBuilder.java:453) ... еще 5


person tomvda    schedule 21.07.2012    source источник
comment
А что какая-то причина на самом деле есть?   -  person A.H.    schedule 21.07.2012


Ответы (2)


Проблема в следующем:

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) /*...*/
person A.H.    schedule 21.07.2012
comment
Совершенно верно, +1. Но с Runtime.getRuntime().exec(startupCommand) должно работать. - person Stephan; 21.07.2012
comment
@Stephan: Это не сработает, потому что эта версия exec разделит команду на пробелы, а jar-path в сообщении об ошибке содержит пробелы, и TO ожидает, что это сработает (replace(...)). - person A.H.; 21.07.2012

Поскольку это еще одна Java-программа, возможно, вы захотите запустить ее в том же процессе, потому что гораздо проще взаимодействовать между двумя программами, если они находятся в одном процессе. Вы пытались запустить команду вне вашей программы? Это работает? Что содержит файл meta-inf.mf в банке? Возможно, путь к классам в файле meta-inf.mf не является относительным, поэтому никакие зависимые файлы jar не могут быть найдены.

person chubbsondubs    schedule 21.07.2012