Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you run an external command from a Java servlet?

I am developing a small web application that requests user input and passes that input as the command line arguments of an external program on the server side machine.

public class WorkflowServlet extends HttpServlet 

  public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
    String username = request.getParameter( "username" );
    String workflow = request.getParameter( "workflow" );
    String preInflation = request.getParamater( "preInflation" );
    String email = request.getParamater( "email" );

    try {
      executeShellCommand( "java ClusterProcess " + username + " "
                            + workflow + " " + preInflation + " " + email );
    } catch ( Exception e ) {
      response.sendRedirect( "WorkflowAction.jsp" ); return;
    }

      response.sendRedirect( "WorkflowInProgress.jsp" );
    }
  }


  public static void executeShellCommand( String command ) {
      Runtime.getRuntime().exec( command.split( " " ) ).waitFor();
  }
}

No exceptions are thrown - it just seems to do nothing. Even if I pass in something really simple such as "touch test.txt" to executeShellCommmand it does nothing. I can successfully run the command manually via the command line.

What must I do?


2 Answers

By not capturing the input stream or error stream you are missing potential feedback from the process. I adapted the following code (outside the comfort of my IDE) from something I had written previously, so I apologize if there are obvious errors.

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
...

String[] commands = {"/usr/bin/touch", "/home/blah/test.txt"};
//this could be set to a specific directory, if desired
File dir = null;
BufferedReader is = null;
BufferedReader es = null;

try
{
    Process process;
    if (dir != null)
        process = Runtime.getRuntime().exec(commands, null, directory);
    else
        process = Runtime.getRuntime().exec(commands);
    String line;
    is = new BufferedReader(new InputStreamReader(process.getInputStream()));
    while((line = is.readLine()) != null)
        System.out.println(line);
    es = new BufferedReader(new InputStreamReader(process.getErrorStream()));
    while((line = es.readLine()) != null)
        System.err.println(line);

    int exitCode = process.waitFor();
    if (exitCode == 0)
        System.out.println("It worked");
    else
        System.out.println("Something bad happend. Exit code: " + exitCode);
} //try
catch(Exception e)
{
    System.out.println("Something when wrong: " + e.getMessage());
    e.printStackTrace();
} //catch
finally
{
    if (is != null)
        try { is.close(); } catch (IOException e) {}
    if (os != null)
        try { es.close(); } catch (IOException e) {}
} //finally
like image 99
jt. Avatar answered Apr 11 '26 12:04

jt.


You're confusing exec()ing something and using a shell that has all sorts of nifty things ... like a search path.

Specify the full path of the process you want to exec(); e.g. /usr/bin/touch or /path/to/java

like image 34
Brian Roach Avatar answered Apr 11 '26 12:04

Brian Roach



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!