Can';t在Windows 7下使用ProcessBuilder在Java中执行javac或其他命令行应用程序

Can';t在Windows 7下使用ProcessBuilder在Java中执行javac或其他命令行应用程序,java,executable,javac,processbuilder,Java,Executable,Javac,Processbuilder,我试图使用ProcessBuilder从Java执行javac,但没有得到任何输出,也没有发生任何事情。我尝试读取输入流(因为有一个bug,如果我不读取它,进程将挂起),但仍然没有结果。我最初将所有必需的参数传递给javac,但它不起作用,所以我将其简化为javac(它应该打印帮助消息) 我试着跑步 “C:\Windows\System32\cmd.exe/C:\\“程序文件\”\Java\jdk1.6.0\u 23\bin\javac.exe” “C:\\“程序文件\”\Java\jdk1.6

我试图使用ProcessBuilder从Java执行javac,但没有得到任何输出,也没有发生任何事情。我尝试读取输入流(因为有一个bug,如果我不读取它,进程将挂起),但仍然没有结果。我最初将所有必需的参数传递给javac,但它不起作用,所以我将其简化为javac(它应该打印帮助消息)

我试着跑步 “C:\Windows\System32\cmd.exe/C:\\“程序文件\”\Java\jdk1.6.0\u 23\bin\javac.exe” “C:\\“程序文件\”\Java\jdk1.6.0\u 23\bin\javac.exe” 并用双引号将整个javac路径括起来,但仍然没有

我得到了错误

无法运行程序“C:\Windows\System32\cmd.exe/C:\“program Files”\Java\jdk1.6.0\u 23\bin\javac.exe”:CreateProcess错误=2,系统找不到指定的文件

但是如果我复制命令并从命令行运行它,它就可以正常工作

我知道使用JavaCompiler类来编译我的文件,但我更希望先解决这个问题,因为我无法从Java运行任何dos应用程序或.bat文件。不过,我可以运行诸如notepad.exe之类的GUI程序

String[]  commands = new String[]{
             "C:\\Windows\\System32\\cmd.exe  /c C:\\\"Program Files\"\\Java\\jdk1.6.0_23\\bin\\javac.exe"
          };

  logger.log(Level.INFO, "About to run javac with the command below:");
  String commandToOutput = "";
  for (String command : commands) {
     commandToOutput += command + " ";
  }
  logger.log(Level.INFO, commandToOutput);



  ProcessBuilder processBuilder = new ProcessBuilder(commands);
  Process p = processBuilder.start();
编辑2

String[] commands = new String[]{
         "C:\\\"Program Files\"\\Java\\jdk1.6.0_23\\bin\\javac.exe", "-d", "\"" + tempDir + "\"", "-classpath", classpath
      };
编辑3

为什么下面第二个命令数组可以工作,而第一个命令数组不能工作

//this gives me CreateProcess error=5, Access is denied
      commands = new String[]{
                 "C:\\\"Program Files\"\\Java\\jdk1.6.0_23\\bin\\javac.exe"
              };

//this works
      commands = new String[]{
                 "C:\\Windows\\System32\\cmd.exe",
                 "/c",
                 "C:\\\"Program Files\"\\Java\\jdk1.6.0_23\\bin\\javac.exe",
              };

您使用了错误的process builder方法。使用单字符串版本,即不传递字符串数组,只传递字符串。字符串数组版本适用于已将命令划分为程序、选项和参数的情况。现在,它正在寻找一个名为
C:\\Windows\\System32\\cmd.exe/C:\\\\\\“program Files\”\\Java\\jdk1.6.0\u 23\\bin\\javac.exe的程序可执行文件

或者,将命令拆分为字符串数组中的程序和参数,然后可以使用process builder的字符串数组版本

String[] = new String[] {
    "C:\\Windows\\System32\\cmd.exe",
    "/c",
    "C:\\\"Program Files\"\\Java\\jdk1.6.0_23\\bin\\javac.exe"
}

而且,您使用了错误的process builder方法。使用单字符串版本,即不传递字符串数组,只传递字符串。字符串数组版本适用于已将命令划分为程序、选项和参数的情况。现在,它正在寻找一个名为
C:\\Windows\\System32\\cmd.exe/C:\\\\\\“program Files\”\\Java\\jdk1.6.0\u 23\\bin\\javac.exe的程序可执行文件

或者,将命令拆分为字符串数组中的程序和参数,然后可以使用process builder的字符串数组版本

String[] = new String[] {
    "C:\\Windows\\System32\\cmd.exe",
    "/c",
    "C:\\\"Program Files\"\\Java\\jdk1.6.0_23\\bin\\javac.exe"
}

而传递给ProcessBuilder的字符串数组应该每个数组元素包含一个参数,而不是一个大字符串中的所有参数

试试这个:

String[] commands = new String[] { "C:\\Windows\\System32\\cmd.exe", "/c", "C:\\\"Program Files\"\\Java\\jdk1.6.0_23\\bin\\javac.exe" }; 字符串[]命令=新字符串[] { “C:\\Windows\\System32\\cmd.exe”, “/c”, “C:\\“程序文件\”\\Java\\jdk1.6.0\u 23\\bin\\javac.exe” }; 顺便说一句:不需要调用cmd.exe,您可以直接将javac.exe传递给ProcessBuilder

ProcessBuilder builder = new ProcessBuilder( "C:\\\"Program Files\"\\Java\\jdk1.6.0_23\\bin\\javac.exe", "\\Path\\To\\MyClass.java" ); ProcessBuilder=新的ProcessBuilder( “C:\\“程序文件”\\Java\\jdk1.6.0\u 23\\bin\\javac.exe“,“\\Path\\To\\MyClass.Java” );
传递给ProcessBuilder的字符串数组应该为每个数组元素包含一个参数,而不是一个大字符串中的所有参数

试试这个:

String[] commands = new String[] { "C:\\Windows\\System32\\cmd.exe", "/c", "C:\\\"Program Files\"\\Java\\jdk1.6.0_23\\bin\\javac.exe" }; 字符串[]命令=新字符串[] { “C:\\Windows\\System32\\cmd.exe”, “/c”, “C:\\“程序文件\”\\Java\\jdk1.6.0\u 23\\bin\\javac.exe” }; 顺便说一句:不需要调用cmd.exe,您可以直接将javac.exe传递给ProcessBuilder

ProcessBuilder builder = new ProcessBuilder( "C:\\\"Program Files\"\\Java\\jdk1.6.0_23\\bin\\javac.exe", "\\Path\\To\\MyClass.java" ); ProcessBuilder=新的ProcessBuilder( “C:\\“程序文件”\\Java\\jdk1.6.0\u 23\\bin\\javac.exe“,“\\Path\\To\\MyClass.Java” );
您必须自己读取
process.getInputStream()
。据我所知,进程的输出不会自动显示在标准输出上。

您必须自己从
process.getInputStream()
读取。据我所知,进程的输出不会自动显示在stdout上。

我尝试了这个方法,现在没有收到错误,但在标准输入或错误流上仍然没有javac的输出。当我提供类路径参数时,它也不会生成编译文件。我尝试了这个方法,现在没有得到错误,但是在标准输入或错误流上仍然没有来自javac的输出。当我提供类路径参数时,它也不会生成编译文件。我尝试了你的第一个建议,现在我没有得到错误,但在标准输入或错误流上仍然没有javac的输出。当我提供类路径参数时,它也不会生成编译文件。我已经尝试了你的第二个建议,它会生成“线程中的异常”thread-2“java.lang.AssertionError:未能编译文件。无法运行程序“C:\“program files”\java\jdk1.6.0\u 23\bin\javac.exe”:CreateProcess error=5,访问被拒绝”。顺便说一句,我在NetBeans 6.9.1Well中通过JUnit测试运行它“拒绝访问”是完全不同的,它不是由ProcessBuilder调用产生的。很可能您没有为javac调用提供输出目录,因此它试图写入c:\Program文件,这是普通用户无法做到的。是的,这是我的想法,但我是作为管理员运行的,我在问题中添加了我正在运行的命令。Temp directory是与我的源代码(不在程序文件中)处于同一级别的目录,classpath是编译所需的java文件和JAR的列表。好的,这部分是我的错误,我在读取输入的线程中有一个bug,所以我什么都看不到。一旦我确定第一个解决方案有效,但第二个解决方案给我一个“CreateProcess错误=5,访问被拒绝”。请参阅上面的编辑3。我尝试了你的第一个建议,现在我没有收到错误,但在标准输入或错误流上仍然没有javac的输出。当我提供类路径参数时,它也不会生成编译文件