2012-07-21 56 views
3

我一直在努力了一段时间,现在这个问题,我似乎无法修复它。 我已经尝试了不同的方法(Runtime.exec(),ProcessBuiler),但似乎没有工作。Java在Linux上执行进程

这是我的问题。 我有一个永远在线的笔记本电脑。这台笔记本电脑运行一个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的罐子”/用户/梦游者/ Dropbox的/开发/源代码/ Java的/ NightWare工具/家庭自动化/家庭自动化执行人/距离/ Home_Automation_Executor .jar“”:error = 2,在java.lang.ProcessBuilder.start(ProcessBuilder.java:460) home.automation.executor.webserver.HTTPGenerator._handleActionCommand(HTTPGenerator.java:190) at home.automation.executor.webserver.HTTPGenerator._generateHTTPPage(HTTPGenerator.java:165) at home.automati on.executor.webserver.HTTPGenerator.getHTTPPage(HTTPGenerator.java:58) at home.automation.executor.webserver.HTTPRequestHandler.run(HTTPRequestHandler.java:160) 导致:java.io.IOException:error = 2,没有这样的文件或目录 at java.lang.UNIXProcess.forkAndExec(Native Method) at java.lang.UNIXProcess。(UNIXProcess.java:53) at java.lang.ProcessImpl.start(ProcessImpl.java:91) 在java.lang.ProcessBuilder.start(ProcessBuilder.java:453) ... 5个

+0

这 “某种原因”,实际上是? – 2012-07-21 16:25:04

回答

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) /*...*/ 
+0

绝对正确,+1。但是使用'Runtime.getRuntime().exec(startupCommand)'它应该可以工作。 – Stephan 2012-07-21 16:43:13

+0

@Stephan:这是行不通的,因为那个'exec'版本会将命令拆分为空格,并且错误消息中的jar-path包含空格_and_TO期望它能够工作('replace(...) )。 – 2012-07-21 16:57:05

+0

先生,你救了我一天! – NightWalker 2012-07-21 20:03:32

1

既然是另一个Java程序,你可能要考虑在同一个进程中运行它,因为它更容易沟通在t之间如果他们生活在同一个过程中,他就是两个节目。你有没有试过在你的程序之外运行命令?它工作吗? jar中的meta-inf.mf文件包含什么内容?这可能是因为meta-inf.mf文件中的类路径不是相对的,所以无法找到任何相关的jar。