Java Runtime.getRuntime()非法参数异常

问题描述:

我在使.getruntime.exec()正常工作时遇到了一些问题。下面是处理该部分的代码:Java Runtime.getRuntime()非法参数异常

while (line != null) 
{ 
    String name = line; 
    String commandFull = commandFirst + name + commandLast; 

    String[] fullCommand = new String[] {commandFirst, name, commandLast}; 
    for(int i=0;i<3;i++) 
    { 
    System.out.print(fullCommand[i]); 
    } 
    Runtime runner = Runtime.getRuntime(); 
    Process p = runner.exec(fullCommand); 

    outFile.println(fullCommand); 

    line = inFile.readLine(); 
} 

它打印出它应该看起来的命令。当我在这里运行程序时,输出是:

adfind -b dc=stuff,dc=com -f "cn=user" |find "displayName" >> fullList.txt 
Exception in thread "main" java.lang.IllegalArgumentException 
     at java.lang.ProcessImpl.<init>(Unknown Source) 
     at java.lang.ProcessImpl.start(Unknown Source) 
     at java.lang.ProcessBuilder.start(Unknown Source) 
     at java.lang.Runtime.exec(Unknown Source) 
     at java.lang.Runtime.exec(Unknown Source) 
     at lookup.main(lookup.java:41) 

您试图在没有shell的情况下执行shell命令。

也就是说,您正在尝试执行shell将解释的内容(特别是管道'|'和附加'>>')。为了解决这个问题,让Java执行一个shell实例并将整个命令传递给shell。这将如何工作取决于平台。

例如在Linux中:

String fullCommand = {"/bin/sh", "-c", "find -b dc=stuff,dc=com -f \"cn=user\" |find \"displayName\" >> fullList.txt"}; 

或Windows:

String fullCommand = {"cmd.exe", "/c", "find -b dc=stuff,dc=com -f \"cn=user\" |find \"displayName\" >> fullList.txt"}; 

我猜 “追加”(>>)和 “管”(|)是不允许的。

您可以通过给每个项目在数组中的地方试试:

String [] command = {"adfind" "-b" "dc=stuff,dc=com" "-f" "cn=user" "|" "find" "displayName" ">>" "fullList.tx" } 

看看会发生什么。

重定向和管道不起作用 - 它们不是命令的一部分,但是当您从e运行此行时,依赖于基础shell进行评估。 G。一个cmd.exe窗口。

您将需要使用从exec()方法获得的Process对象的输入和输出流。

如果您主要关心的是查询Active Directory,而不是使用特定的查询工具,则应考虑采用全Java解决方案。有几种方法来访问LDAP目录(Active Directory所也是),例如这里:

http://developer.novell.com/wiki/index.php/Jldap

我没有用它自己,然而它似乎并不被遗弃的,因为有从2008年的版本。

正如其他人指出的那样,您不能通过shell指令执行stdout/err重定向,因为您没有shell。

您需要在单独的线程中使用stdout/stderr,以防止阻塞。有关更多信息,请参阅this answer

最后(是的,这是一种快速和肮脏的方式)我最终调用一个.bat文件执行命令,并使用管道和重定向。我相信这不是最好的解决方案,但它适用于我所需要的。