4

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();
    }
}
dorjeduck
  • 7,006
  • 10
  • 45
  • 62
  • 1
    Post the Exception / Error you get – CloudyMarble Sep 17 '12 at 05:21
  • {"error":"unauthorized"} – dorjeduck Sep 17 '12 at 05:23
  • do you get an exception? which errorcode and Message does it have? or is the output showing unauthorized? – CloudyMarble Sep 17 '12 at 05:30
  • error response with the posted response json – dorjeduck Sep 17 '12 at 05:43
  • my question is really more about what can make the difference between the Runtime.getRuntime().exec() command execution and executing the very same command in a shell – dorjeduck Sep 17 '12 at 05:44
  • Don't forget, any child process you create will inherit it's parents permission/access rights. Make sure that Java is running with the any required permissions. – MadProgrammer Sep 17 '12 at 05:48
  • Administration rights! but this shouldnt affect the Curl responce – CloudyMarble Sep 17 '12 at 05:49
  • Just did Runtime.getRuntime().exec("which curl") and found out that is is using another curl than the curl used in the shell - crappy setup. Nevertheless when i call curl with the full path as it is used in the shell it still doesnt work. So as i have to move on I just did something ugly but working. I wrote a shell script executing the curl and call that shell script from within java and that works for now ... – dorjeduck Sep 17 '12 at 06:37

2 Answers2

4

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)

Community
  • 1
  • 1
Andreas Lundgren
  • 10,546
  • 3
  • 18
  • 31
  • You saved my life sir. I banged my head a few hours against this wall. I wanted to simply upload a file with curl from gradle (As a quick implementation) That took way longer than expected Cheers! – Larusso Jan 25 '18 at 22:34
  • You saved my life. Thank you very much. – passerbywhu Feb 25 '20 at 06:14
0

I guess you get an Errorcode from Curl not the exception, check the Curl API again, u guess you will find any missing parameter like "User" or other stuff.

You can try to check some of the hints mentioned in this answer.

Community
  • 1
  • 1
CloudyMarble
  • 34,949
  • 69
  • 92
  • 126
  • thanks - yes not an exception but an error response as mentioned . The very same curl command works when executed in a shell so it really doesnt seem to be a problem at that side of the Curl API... – dorjeduck Sep 17 '12 at 05:42
  • i saw this other post but for simplicity i decided to go for Runtime as suggested in one comments there – dorjeduck Sep 17 '12 at 05:50