Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

mpcoder

macrumors newbie
Original poster
Mar 21, 2009
16
0
I want to open applications using
Code:
Runtime.getRuntime().exec()
but I'm having a problem when the application's name has a space in it for example with "Quicktime Player.app" When I do this:
Code:
Runtime.getRuntime().exec("open \"/Applications/Quicktime Player.app\"")
it doesn't work. So to eliminate the escaping of the quotes (\") I renamed it Quicktime.app and tried
Code:
Runtime.getRuntime().exec("open /Applications/Quicktime.app")
and it worked fine. Then for some reason when I tried it again without the space but with the escaped quotes
Code:
Runtime.getRuntime().exec("open \"/Applications/Quicktime.app\"")
it doesn't work!! Even without the space!

Any ideas?
 

mpcoder

macrumors newbie
Original poster
Mar 21, 2009
16
0
Thanks for your reply lee.

I tried that just now and no dice. The strange thing is that when I write it myself on the command line with the escaped quotes it works just fine, the problem apparently occurs when sending it through that java method.
 

Guiyon

macrumors 6502a
Mar 19, 2008
771
4
Cambridge, MA
Try this method:

Code:
String[] cmd = new String[] { "/usr/bin/open", // The command
                              "--wait-apps", // Block until the app is closed, optional
                              "/Applications/QuickTime Player.app"
                            };

/* Will not return until QuickTime exists because of the 
*   --wait-apps argument
*/
Process qt = Runtime.getRuntime().exec( cmd );


Here's a quick test class demonstrating its use (just name it "test.java"). This isn't the cleanest code but it's a quick & simple example:
Code:
import java.io.*;

public class test {
  public static void main (String [] args)
  {
    try {
      String[] cmd = new String[] { "/usr/bin/open", // The command
                                    "--wait-apps", // Block until the app is closed
                                    "/Applications/QuickTime Player.app"
                                  };
                                  
      Process qt = Runtime.getRuntime().exec( cmd );
      
      if( qt == null ) {
        System.out.println( "Error while exec'ing command." );  
      } else {
        int result = -1;
        char[] buf = new char[256];
        StringBuffer sb = new StringBuffer();
        Reader isr = new InputStreamReader( qt.getErrorStream() );
        
        while( (result = isr.read(buf, 0, buf.length)) != -1 ) {
          sb.append( buf, 0, result );
        }
        
        if( sb.length() > 0 ) {
          System.out.println( "STDERR said:\n"+sb.toString() );
          System.out.println( "*********" );
        }
        
        
        /* Finished up with the STDERR output, now print the
        *   STDOUT
        */
        sb = new StringBuffer();
        isr = new InputStreamReader( qt.getInputStream() );
        while( (result = isr.read(buf, 0, buf.length)) != -1 ) {
          sb.append( buf, 0, result );
        }

        if( sb.length() > 0 ) {
          System.out.println( "STDOUT said:\n"+sb.toString() );
          System.out.println( "*********" );
        }
      }
    } catch( IOException ioe ) {
      System.out.println( "Exception: "+ioe );
    }
  }
}
 

macsmurf

macrumors 65816
Aug 3, 2007
1,200
948
The quotes is for the benefit of your terminal shell in order for it to interpret your command properly. You're not going through bash (or similar) in java, so the quotes will be interpreted as a part of the filename.

In addition, you're using a convenience method in Runtime that does not work well with spaces because, according to the documentation and the source-code, exec uses a standard StringTokenizer to convert the command from a String to a String Array. Here is the problem:

Code:
public Process exec(String command, String[] envp, File dir)
        throws IOException {
        if (command.length() == 0)
            throw new IllegalArgumentException("Empty command");

	StringTokenizer st = new StringTokenizer(command);
	String[] cmdarray = new String[st.countTokens()];
 	for (int i = 0; st.hasMoreTokens(); i++)
	    cmdarray[i] = st.nextToken();
	return exec(cmdarray, envp, dir);
}

So, in order for you to ensure that the command is interpreted properly, you need to construct the String array yourself. In other words, do what Guiyon suggested :)
 

mpcoder

macrumors newbie
Original poster
Mar 21, 2009
16
0
Wow that was it! I built the array myself and it worked.

Thank you all for your quick responses!
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.