Java – using curl with Runtime.getRuntime().exec

commandcurljava

I want to use curl within a java program using Runtime.getRuntime().exec

The full snippet is below yet what my problem boils down to is that I get an error response when I use the curl command in Runtime.getRuntime().exec(command) but when I System.out.println the command, copy and paste it to a shell and execute it there it works fine.

System.out.println(command);
Runtime.getRuntime().exec(command);

What could cause this different outcome between runtime exec and executing the command in the shell.

Thanks for any hints

martin

updates:

  • The error response I get when using Runtime is: {"error":"unauthorized"}

  • As I see from the commands that seems to be unclear. I dont get any Exception the curl command runs through but the json response is as posted above.


String APP_ID = "XXX";
String REST_API_KEY = "YYY";

String header = "-H \"X-Parse-Application-Id: " + APP_ID
        + "\" -H \"X-Parse-REST-API-Key: " + REST_API_KEY
        + "\" -H \"Content-Type: application/zip\" ";

public void post2Parse(String fileName) {

    String outputString;

    String command = "curl -X POST " + header + "--data-binary '@"
            + fileName + "' https://api.parse.com/1/files/" + fileName;

    System.out.println(command);

    Process curlProc;
    try {
        curlProc = Runtime.getRuntime().exec(command);

        DataInputStream curlIn = new DataInputStream(
                curlProc.getInputStream());

        while ((outputString = curlIn.readLine()) != null) {
            System.out.println(outputString);
        }

    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
}

Best Answer

I don't have a direct answer, but a bit on the way is that the apostrophe gets encoded differently. Although an old question, I'll answer to for future reference, and maybe someone can explain the complete answer later.

When I test our API in a similar way I notice the following:

curl -i http://localhost:8080/auth/login -d 'identifier=test@example.com&password=test'

This command, when sent from shell, ends up in the server as:

identifier=test@example.com,\npassword=test,\n

but when sent from Runtime.getRuntime().exec(command), it ends up as:

'identifier=test@example.com,\npassword=test',\n

If I change the curl command and remove the apostrophes, it works (due to the essence of this command)

 curl -i http://localhost:8080/auth/login -d identifier=test@example.com&password=test

Thus a fait guess is that if the code in the question is changed to this, it may actually work if the file name contains no space...:

String command = "curl -X POST " + header + "--data-binary @"
        + fileName + " https://api.parse.com/1/files/" + fileName;

One option would be to use the execute command with an array of inputs as described here: Runtime Exec seems to be ignoring apostrophes In combination of parsing the curl command (unless hard coded) as described here: Split string on spaces in Java, except if between quotes (i.e. treat \"hello world\" as one token)