1

I am trying to execute windows commands from Java using the following code,

Process p=Runtime.getRuntime().exec("wget www.anyurl.com/index.html);

and it works but when I try to execute another command which is as follows,

Process p1=Runtime.getRuntime().exec("pscp -pw sysadmin c:/mydirectory/mypage.html mahesh@vmstni01:/home/usr");

it does not seem to work. If I comment out the first process line (ie Process p) then the process p1 is working fine, it executes and shows that file has been copied successfully. Please can anyone tell me why this is happening?

jpe
  • 1,013
  • 6
  • 14
Mahesh
  • 39
  • 1
  • 4
  • 9
  • Define "it won't work". What happens? – JB Nizet Jun 24 '12 at 18:46
  • does the first command have to be completed before the second one can be called successfully? – David Kroukamp Jun 24 '12 at 18:47
  • Hi JB Nizet, first command works fine (i e wget) but when I try to execute pscp it is not working and if I comment first line (ie Process p=Runtime.getRuntime().exec("wget www.anyurl.com/index.html); ) then pscp is working fine. – Mahesh Jun 24 '12 at 19:00
  • *"It doesn't work"* doesn't explain what happens. Does the program hang? Does it throw an exception? If so, what's the stack trace? Does it do something other than what you expect? If so what do you expect it to do and what does it do instead? When you go to a doctor, you don't just say: I'm sick. You tell all the symptoms, to help him identify what's wrong. Do the same here. – JB Nizet Jun 24 '12 at 19:20

1 Answers1

4

You need to clean up the streams of the first process, otherwise the program will block because the "wget" process produces output that is never read in your current implementation. You need to sort out the output and error streams of the first process. Look at answers to e.g. another question about java-runtime-exec on SO.

The code below works for reference, but relies on the fact that wget generates output to stderr and pscp to stdout. If anything gets output to the other corresponding stream, the code works as long as the output fits into the buffer of the Java program (please note that these buffer sizes tend to be different from platform to platform) while it empties the first stream. If the buffer gets full, the execution of the command simply blocks. You should create a separate thread for both, stout and stderr that reads the appropriate stream of the process.

    import java.io.BufferedReader;
    import java.io.InputStreamReader;

...

    Process p=Runtime.getRuntime().exec("wget http://www.duckduckgo.com/");

    BufferedReader perr=new BufferedReader(new InputStreamReader(p.getErrorStream()));
    BufferedReader pout=new BufferedReader(new InputStreamReader(p.getInputStream()));
    // We read stderror first from wget, because it spits the progress information into stderr
    for (String s=perr.readLine(); s!=null; s=perr.readLine())
    {
        System.out.println("Stderr from p: "+s);
    }
    for (String s=pout.readLine(); s!=null; s=pout.readLine())
    {
        System.out.println("Stdout from p: "+s);
    }
    // if you need to check whether the command actually returned normally
    int returnCode = p.waitFor();
    perr.close();
    pout.close();

    System.out.println("Returned from p with exit code "+returnCode);

    p=Runtime.getRuntime().exec("pscp -pw dontuseplainpwusesshkeys index.html user@10.0.0.11:");
    perr=new BufferedReader(new InputStreamReader(p.getErrorStream()));
    pout=new BufferedReader(new InputStreamReader(p.getInputStream()));
    // We read stdout of pscp first because pscp spits stuff into stdout.
    // The process will block if the buffer gets full and does not get emptied.
    for (String s=pout.readLine(); s!=null; s=pout.readLine())
    {
        System.out.println("Stdout from p: "+s);
    }
    for (String s=perr.readLine(); s!=null; s=perr.readLine())
    {
        System.out.println("Stderr from p: "+s);
    }

    int returnCode1 = p.waitFor();
    perr.close();
    pout.close();

    System.out.println("Process exited with return code "+returnCode1);
Community
  • 1
  • 1
jpe
  • 1,013
  • 6
  • 14
  • Hi David, first command is working fine before second command executes – Mahesh Jun 24 '12 at 18:55
  • Hi jpe, I am trying with yours suggestion and get back to you. – Mahesh Jun 24 '12 at 18:57
  • Hi Guys, here I am providing my code please have look into it and tell me what wrong with this code, String input;BufferedReader br; br = new BufferedReader( new InputStreamReader( System.in ) ); input=br.readLine(); if(input.equals("download")) { Process p=Runtime.getRuntime().exec("wget www.anyurl.com/index.html); } else if(input.equals("upload")) { Process p1=Runtime.getRuntime().exec("pscp -pw sysadmin c:/mydirectory/mypage.html mahesh@vmstni01:/home/usr"); } – Mahesh Jun 25 '12 at 00:51
  • Look at the following post about p.getInputStream() and p.getErrorStream(): http://stackoverflow.com/a/8597030/1424507 – jpe Jun 25 '12 at 05:18
  • Will you please modify my above code and tell me how it will look like. I tried with your suggestion but still not have success in my hands. – Mahesh Jun 26 '12 at 20:56
  • @Mahesh Added some code for your reference that illustrates your problem but does not contain a final implementation. Please read the linked posts and also the SDK documentation about runtime.exec(). – jpe Jun 27 '12 at 07:47
  • I tried with this and working fine on windows 7 but when I execute on windows xp it still not showing any output. There is no error or exception generated while running this program on windows xp. Is there any platform dependency related with this. – Mahesh Jun 28 '12 at 14:52
  • @Mahesh Please read the post "The code below works for reference, but is not 100% correct. It currently relies on the fact that whatever gets sent to standard output fits into the buffer of the Java program (please note that these buffer sizes tend to be different from platform to platform)". Since pscp generates output to stdout, you may be able to fix things for your purpose by doing a for(String s=pout.readline... cycle before the perr one. – jpe Jun 28 '12 at 17:04
  • Thanks this code is working fine on both OS. Thanks a lot for your help. – Mahesh Jun 30 '12 at 18:43