Better way to do error handling here?

Discussion in 'Java' started by laredotornado, Oct 19, 2009.

  1. Hi,

    I'm using Java 1.5. At a certain point in my program, I have this
    code:

    phpProcess = Runtime.getRuntime().exec(phpNormalizerCommand);
    stdoutReader =
    new BufferedReader
    (new InputStreamReader(phpProcess.getInputStream()));
    stdinWriter =
    new PrintWriter
    (new OutputStreamWriter(phpProcess.getOutputStream()));

    Later I use the stdoutReader and stdinWriter variables. The
    "phpNormalizerCommand" variable runs a script that depends on PHP.
    However, if PHP is not installed on the machine, the command would
    normally print

    /usr/bin/php5: bad interpreter: No such file or directory

    from a termianl . Is there some way after first ilne of the code above
    that I could trap for this error and stop my program if I detect such
    an error?

    Thanks, - Dave
     
    laredotornado, Oct 19, 2009
    #1
    1. Advertising

  2. laredotornado

    Stefan Ram Guest

    laredotornado <> writes:
    > phpProcess = Runtime.getRuntime().exec(phpNormalizerCommand);
    >from a termianl . Is there some way after first ilne of the code above
    >that I could trap for this error and stop my program if I detect such
    >an error?


    Usually, the following pattern might work:

    try
    { phpProcess = Runtime.getRuntime().exec(phpNormalizerCommand);
    if( phpProcess == null )handleNullProcessResult();
    else use( phpProcess ); }
    catch( final java.lang.Throwable throwable )
    { handle( throwable ); }

    After you found the precise type of the error, you should
    restrict the catch clause to catch only this.

    (I have not looked up the docs and therefore might have
    missed something.)
     
    Stefan Ram, Oct 19, 2009
    #2
    1. Advertising

  3. laredotornado

    Ian Shef Guest

    -berlin.de (Stefan Ram) wrote in news:error-catching-
    -berlin.de:

    > laredotornado <> writes:
    >> phpProcess = Runtime.getRuntime().exec(phpNormalizerCommand);
    >>from a termianl . Is there some way after first ilne of the code above
    >>that I could trap for this error and stop my program if I detect such
    >>an error?

    >
    > Usually, the following pattern might work:
    >
    > try
    > { phpProcess = Runtime.getRuntime().exec(phpNormalizerCommand);
    > if( phpProcess == null )handleNullProcessResult();
    > else use( phpProcess ); }
    > catch( final java.lang.Throwable throwable )
    > { handle( throwable ); }
    >
    > After you found the precise type of the error, you should
    > restrict the catch clause to catch only this.
    >
    > (I have not looked up the docs and therefore might have
    > missed something.)


    The javadocs are your friend:

    "Starting an operating system process is highly system-dependent. Among the
    many things that can go wrong are:

    The operating system program file was not found.
    Access to the program file was denied.
    The working directory does not exist.

    In such cases an exception will be thrown. The exact nature of the
    exception is system-dependent, but it will always be a subclass of
    IOException."

    In fact, the javadocs provide this at the begining of the definition for
    exec:

    public Process exec(String command) throws IOException

    The original poster should know this and omitted some important code in the
    snippet that was posted.

    It might have been simpler to modify phpNormalizerCommand and test the
    result than it was to post to the newsgroup.

    I tested on WindowsXP using JDK 1.6.0_14 using
    the following test program:

    package testpack1;
    import java.io.IOException;
    public class ExecNonExistentProgram {
    public static void main(String[] args) {
    try {
    Runtime.getRuntime().exec("nonexistent");
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }

    which generates:

    java.io.IOException: Cannot run program "nonexistent": CreateProcess error=
    2, The system cannot find the file specified
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)
    at java.lang.Runtime.exec(Runtime.java:593)
    at java.lang.Runtime.exec(Runtime.java:431)
    at java.lang.Runtime.exec(Runtime.java:328)
    at testpack1.ExecNonExistentProgram.main
    (ExecNonExistentProgram.java:15)
    Caused by: java.io.IOException: CreateProcess error=2, The system cannot
    find the file specified
    at java.lang.ProcessImpl.create(Native Method)
    at java.lang.ProcessImpl.<init>(ProcessImpl.java:81)
    at java.lang.ProcessImpl.start(ProcessImpl.java:30)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:452)
    ... 4 more

    which then suggested:

    package testpack1;
    import java.io.IOException;
    public class ExecNonExistentProgram2 {
    public static void main(String[] args) {
    try {
    (new ProcessBuilder("nonexistent")).start() ;
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }

    which generates:

    java.io.IOException: Cannot run program "nonexistent": CreateProcess error=
    2, The system cannot find the file specified
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)
    at testpack1.ExecNonExistentProgram2.main
    (ExecNonExistentProgram2.java:6)
    Caused by: java.io.IOException: CreateProcess error=2, The system cannot
    find the file specified
    at java.lang.ProcessImpl.create(Native Method)
    at java.lang.ProcessImpl.<init>(ProcessImpl.java:81)
    at java.lang.ProcessImpl.start(ProcessImpl.java:30)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:452)
    ... 1 more
     
    Ian Shef, Oct 19, 2009
    #3
  4. In article
    <>,
    laredotornado <> wrote:

    > I'm using Java 1.5. At a certain point in my program, I have this
    > code:
    >
    > phpProcess = Runtime.getRuntime().exec(phpNormalizerCommand);
    > stdoutReader =
    > new BufferedReader
    > (new InputStreamReader(phpProcess.getInputStream()));
    > stdinWriter =
    > new PrintWriter
    > (new OutputStreamWriter(phpProcess.getOutputStream()));
    >
    > Later I use the stdoutReader and stdinWriter variables. The
    > "phpNormalizerCommand" variable runs a script that depends on PHP.
    > However, if PHP is not installed on the machine, the command would
    > normally print
    >
    > /usr/bin/php5: bad interpreter: No such file or directory
    >
    > from a termianl . Is there some way after first ilne of the code above
    > that I could trap for this error and stop my program if I detect such
    > an error?


    You need to read the Process's error stream via getErrorStream().
    ProcessBuilder allows merging stout and sterr, which maybe useful in
    this case:

    <http://java.sun.com/javase/6/docs/api/java/lang/ProcessBuilder.html>

    --
    John B. Matthews
    trashgod at gmail dot com
    <http://sites.google.com/site/drjohnbmatthews>
     
    John B. Matthews, Oct 19, 2009
    #4
  5. laredotornado

    Tom Anderson Guest

    On Mon, 19 Oct 2009, Ian Shef wrote:

    > -berlin.de (Stefan Ram) wrote in news:error-catching-
    > -berlin.de:
    >
    >> laredotornado <> writes:
    >>> phpProcess = Runtime.getRuntime().exec(phpNormalizerCommand);
    >>> from a termianl . Is there some way after first ilne of the code above
    >>> that I could trap for this error and stop my program if I detect such
    >>> an error?

    >
    > The javadocs are your friend:
    >
    > "Starting an operating system process is highly system-dependent. Among the
    > many things that can go wrong are:
    >
    > The operating system program file was not found.
    > Access to the program file was denied.
    > The working directory does not exist.
    >
    > In such cases an exception will be thrown. The exact nature of the
    > exception is system-dependent, but it will always be a subclass of
    > IOException."


    None of those are relevant to this situation.

    Here, we know that the script being run exists. But the script specifies
    an interpreter which may or may not exist - this is a unix thing which i
    think doesn't have an equivalent on windows, but basically, a script can
    specify which interpreter should run it on its first line, so you can have
    scripts for the shell, perl, python, and PHP all happily coexisting and
    being run in the same way. If the specified interpreter doesn't exist, the
    script will fail.

    I had a quick poke at this on OS X, and what happens in the case of a bad
    interpreter is that you get no output on either stream, and an exit code
    of 255. If you run the command with "bash -c /path/to/file", then you get
    the "bad interpreter" message on the error stream, and an exit status of
    126.

    You could try something like:

    Process proc = Runtime.getRuntime().exec("/path/to/script");
    Thread.sleep(100); // long enough for the
    try {
    int exit = proc.exitValue();
    throw new IOException("script died with status " + exit);
    }
    catch (IllegalThreadStateException e) {
    // script has not exited - assume it is now running
    }
    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
    BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
    // etc

    Although that 100 is very much a magic number.

    To be honest, i think your best bet is just to start writing your data to
    the script, and catch the broken pipe exception that will happen if the
    script craps out.

    tom

    --
    NO REAL THAN YOU ARE -- Ego Leonard, The Zandvoort Man
     
    Tom Anderson, Oct 20, 2009
    #5
  6. laredotornado

    Arne Vajhøj Guest

    laredotornado wrote:
    > I'm using Java 1.5. At a certain point in my program, I have this
    > code:
    >
    > phpProcess = Runtime.getRuntime().exec(phpNormalizerCommand);
    > stdoutReader =
    > new BufferedReader
    > (new InputStreamReader(phpProcess.getInputStream()));
    > stdinWriter =
    > new PrintWriter
    > (new OutputStreamWriter(phpProcess.getOutputStream()));
    >
    > Later I use the stdoutReader and stdinWriter variables. The
    > "phpNormalizerCommand" variable runs a script that depends on PHP.
    > However, if PHP is not installed on the machine, the command would
    > normally print
    >
    > /usr/bin/php5: bad interpreter: No such file or directory
    >
    > from a termianl . Is there some way after first ilne of the code above
    > that I could trap for this error and stop my program if I detect such
    > an error?


    Other have already discussed the funny world of Runtime exec.

    But instead of running PHP as an external executable, then you could
    consider running the PHP code inside the JVM. Both Caucho and IBM
    has created products to allow that.

    Arne
     
    Arne Vajhøj, Oct 23, 2009
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Paul Rubin
    Replies:
    5
    Views:
    427
    Hendrik van Rooyen
    Aug 6, 2009
  2. George Hester

    Try over here likely more to the point here

    George Hester, Sep 30, 2004, in forum: Javascript
    Replies:
    0
    Views:
    119
    George Hester
    Sep 30, 2004
  3. FAQ server
    Replies:
    0
    Views:
    160
    FAQ server
    Aug 10, 2006
  4. FAQ server
    Replies:
    0
    Views:
    137
    FAQ server
    Oct 7, 2006
  5. Replies:
    2
    Views:
    61
    Mark H Harris
    May 13, 2014
Loading...

Share This Page