2

I'm trying to execute a shell script from Java.The script is supposed to download the file from the URL using wget.Here goes my code.

     public class RunShellScriptFromJava {
         public static void main(String a[]) {
         try {
              ProcessBuilder pb = new ProcessBuilder("/bin/sh","script.sh");
              Process p = pb.start();
              p.waitFor();
              System.out.println("Success");
         } catch (Exception e) {
         e.printStackTrace();
      }
     }
    }

Content of script.sh

     echo "start"
     wget http://alex.smola.org/drafts/thebook.pdf
     echo "end"

My Question: Is this the right way doing it?If not please point me in the right direction.It doesn't throw any exception but I see that the file is not getting downloaded.Any lead/help is appreciated.

Thanks.

PS:I have given execute permission for the script

shadow_coder
  • 113
  • 2
  • 10
  • A script run from Java doesn't get your normal shell environment. Either rewrite your script to work without it (i.e. fullpath everything), or see the linked duplicate about how to set the environment for the `ProcessBuilder`. – azurefrog Dec 22 '15 at 18:49

3 Answers3

1

The code sample in the question lacks error handling around the usage of ProcessBuilder, so it's likely that some kind of error happened, but you aren't getting visibility into it.

The return code of Process#waitFor is being ignored. The returned value is the exit code of the spawned process. I recommend checking to see if this value is non-zero.

There is also no handling of stdout or stderr, so you won't know if the spawned process is writing any output that explains what happened. You can access stdout and stderr by using Process#getInputStream and Process#getErrorStream respectively.

Note also that it is possible for your process to hang if it fails to fully consume the streams, or at least redirect them. I've noticed this problem is particularly common on Windows. A standard technique is to spawn background threads to consume the streams. This previous question discusses that technique and others.

Java ProcessBuilder: Resultant Process Hangs

After the error handling in the Java code is enhanced like this, I expect you'll have a better chance of diagnosing what went wrong with the script.

Community
  • 1
  • 1
Chris Nauroth
  • 9,614
  • 1
  • 35
  • 39
1

The right way to do this is to use Java to download the file instead of the shell script. The problem with shell scripts is that they are system dependent. By using them you lose one of the main benefits of java which is system independence. There are a number of libraries in Java that will accomplish that functionality. The following will work for you using the FileUtils class from apache IO Commons.

URL url = new URL("http://alex.smola.org/drafts/thebook.pdf");
File download = new File('.');
FileUtils.copyURLToFile(url, download);
Adam
  • 406
  • 3
  • 6
0

This script and java example works, perhaps specify the full path to wget to ensure you know where the pdf is being saved.

$ javac RunShellScriptFromJava.java
$ java RunShellScriptFromJava
Success
$ ls
RunShellScriptFromJava.java  thebook.pdf RunShellScriptFromJava.class  script.sh

Example/updated script:

wget -O /home/MYSER/test.pdf http://alex.smola.org/drafts/thebook.pdf
emsworth
  • 1,149
  • 10
  • 21
  • Oh yes.Thats what I was missing!I specified the location like this. wget -P /Users/Ashray/coding/test http://alex.smola.org/drafts/thebook.pdf. And It showed up! Thanks! :) – shadow_coder Dec 22 '15 at 18:59
  • Great! Chris Nauroth's suggestion to check the error code is sound advice, you should do that also. – emsworth Dec 22 '15 at 19:07
  • Yes! I was just checking if this works.I'll consider them when I'm implementing it in my project – shadow_coder Dec 22 '15 at 19:14