Can';t在Windows 7下使用ProcessBuilder在Java中执行javac或其他命令行应用程序
我试图使用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程序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
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的输出。当我提供类路径参数时,它也不会生成编译文件