Question

I'm having some problems with getting the .getruntime.exec() to work properly. Here is the code dealing with that part:

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();
}

It prints out the command as it should look. When I run the program here is the output:

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)
Was it helpful?

Solution

You are trying to execute a shell command without the shell.

That is, you are trying to execute something that a shell would interpret (specifically the pipe '|' and append '>>'). To solve this, have Java execute a shell instance and pass the entire command to the shell. How this would work is platform dependent.

For instance in Linux:

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

Or in Windows:

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

OTHER TIPS

The redirections and pipes do not work - they are not a part of the command, but rely on the underlying shell to be evaluated when you run this line from e. g. a cmd.exe window.

You will need to use the input and output streams of the Process object you get from the exec() method.

If your main concern is to query Active Directory, not using the specific query tool at hand, you should consider going for an all-Java solution. There are several ways to access LDAP directories (which Active Directory also is), for example here:

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

I have not used it myself yet, however it does not seem abandoned as there are releases from 2008.

I guess the "append" (>>) and the "pipe" (|) are not allowed.

You could try it by giving each item a place in the array:

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

And see what happens.

As others have pointed out, you can't perform stdout/err redirection via shell instructions, since you don't have a shell.

You will need to consume stdout/stderr in separate threads, to prevent blocking. See this answer for more information.

In the end (and yes, this was a bit of a quick and dirty way) I ended up calling a .bat file that executed the command and used the pipes and redirects. I'm sure it isn't the best solution but it works for what I need.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top