Solved

Difference in executing a program from command line and from a Java program (i.e. using Runtime)

Posted on 2004-10-28
350 Views
Last Modified: 2007-12-19
Hi All,

What is the difference between executing a program from command line and from a Java program (i.e. using Runtime).

e.g. lets say my program is myprog. If I give following in dos prompt, it works

myprog >>  select__history.out -echo -noprompt  -u user -p passwd < myfile


But, if I give the same to Java using following code :

---------------------------------------------------------------------------------------------------------
      String strCommand = "myprog >>  select__history.out -echo -noprompt  -u user -p passwd < myfile";
            
      try {
           String line;
           Process p = Runtime.getRuntime().exec(strCommand );
           BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
           while ((line = input.readLine()) != null) {
             System.out.println(line);
           }
           input.close();
      }
      catch (Exception err) {
           err.printStackTrace();
      }
            
---------------------------------------------------------------------------------------------------------

I get the following error :

unrecognized argument: ">>"

How can I execute this using java?


Thanks
Ajay
0
Question by:avi_india
    27 Comments
     
    LVL 92

    Accepted Solution

    by:
    0
     
    LVL 24

    Expert Comment

    by:sciuriware
    The <, > and >> arguments must be processed by a shell.
    So your commandline on the dosprompt is processed by cmd.exe or command.exe,
    depending on the Windows version.

    All you have to do is put that program before all other characters:


    cmd.exe MyProgram >> ...........

    ;JOOP!
    0
     
    LVL 12

    Expert Comment

    by:Giant2
    You must pass the values correctly.
    See here:
    http://www.javaalmanac.com/egs/java.lang/Exec.html

    Bye, Giant.
    0
     

    Author Comment

    by:avi_india
    Have gone thru these links.. Now I can execute these inputs and output for a program separately. I am not able to combine as required.

    Can somebody please help me with that..

    i.e. execute a program taking input from infile and sending output to outfile (or some variable - important is to capture the output). Program will also have some command line options.

    0
     
    LVL 12

    Assisted Solution

    by:Giant2
    Use 2 threads to manage the outputs like the followings:
          /** Manage Error.
           * <br>Use one thread to manage errors reached by program.
           */
          private void manageErrors(){
                th1=new java.lang.Thread(){
                      public void run(){
                            try{
                            String ls_str;
                            DataInputStream ls_in = new DataInputStream(p.getErrorStream());
                            while ((ls_str = ls_in.readLine()) != null) {
                                  System.out.println(ls_str);
                            }//end while
                            }catch (IOException ex){System.out.println(ex);}
                      }};
                th1.start();
          }
          
          /** Manage Output.
           * <br>Use one thread to manage output reached by program.
           */
          private void manageOutput(){
                th2=new java.lang.Thread(){
                      public void run(){
                            try{
                            String ls_str;
                            DataInputStream ls_in = new DataInputStream(p.getInputStream());
                            while ((ls_str = ls_in.readLine()) != null) {
                                  System.out.println(ls_str);
                            }//end while
                            }catch (IOException ex){System.out.println(ex);}
                      }};
                th2.start();
          }

    Where p is the process obtained from the RunTime.exec command. th1 and th2 are the 2 thread listening for data from (error and output) the process.
    Make Process P and Thread th1, th2 instance variable of your class.
    Call these methods after the Runtime.exec call method.

    Hope this help you.
    Bye, Giant.
    0
     

    Author Comment

    by:avi_india
    Hi Giant,

    this helps.. but still it does not deal with input to the program which I achieve using "<" on the command line.
    0
     
    LVL 11

    Expert Comment

    by:cjjclifford
    use Process.getOutputStream()

    (from JavaDoc:

    getOutputStream

    public abstract OutputStream getOutputStream()

    Gets the output stream of the subprocess.  Output to the stream is piped into the standard input stream of the process represented by this Process object.

    Implementation note: It is a good idea for the output stream to be buffered.
    )

    So, get this OutputStream, open the file, and write each line of the file (myfile) to be redirected into the program (with "<") to this OutputStream (as recommended, use buffering, so probably better to use java.io.BufferedReader for the input, and java.io.PrintWriter for the output... assuming the file is ASCII, otherwise use java.io.BufferedWriter to write...

    0
     
    LVL 11

    Expert Comment

    by:cjjclifford
    example:
    // exception handling missing...
    BufferedReader in = new BufferedReader( FileReader( "myfile" ) );

    // assuming the Process returned by Runtime.exec() is "myProcess"
    PrintWriter out = new PrintWriter( myProcess.getOutputStream() );

    String line = in.readLine();
    while( line != null ) {
        out.println( line );
        line = in.readLine();
    }

    // getting here means input is complete (should also handle exceptions carefully...)
    out.close();
    0
     
    LVL 86

    Assisted Solution

    by:CEHJ
    Try


    String[] command = { "cmd.exe", "/C", "start", "myprog", ">>",  "select__history.out", "-echo", "-noprompt",  "-u", "user", "-p", "passwd", "<", "myfile" };
    RunAsync.main(command);

    ..............................................


    import java.io.*;

    /**
     *  Description of the Class
     *
     * @author     CEHJ
     * @created    23 February 2004
     */
    public class RunAsync {

      /**
       *  Description of the Method
       *
       * @param  args  Description of the Parameter
       */
      public static void main(String args[]) {

        try {

          if (args.length < 1) {
            System.out.println("Usage: java RunAsync <command string>");
            System.exit(-1);
          }
          Process pro = null;
          if (args.length > 1) {
            pro = Runtime.getRuntime().exec(args);
          }
          else {
            pro = Runtime.getRuntime().exec(args[0]);
          }
          InputStream error = pro.getErrorStream();
          InputStream output = pro.getInputStream();
          Thread err = new Thread(new OutErrReader(error));
          Thread out = new Thread(new OutErrReader(output));
          out.start();
          err.start();
          pro.waitFor();
        }
        catch (java.io.IOException e) {
          e.printStackTrace();
        }
        catch (java.lang.InterruptedException e) {
          e.printStackTrace();
        }

      }


      /**
       *  Description of the Class
       *
       * @author     CEHJ
       * @created    23 February 2004
       */
      static class OutErrReader implements Runnable {
        InputStream is;


        /**
         *Constructor for the OutErrReader object
         *
         * @param  is  Description of the Parameter
         */
        public OutErrReader(InputStream is) {
          this.is = is;
        }


        /**
         *  Main processing method for the OutErrReader object
         */
        public void run() {
          try {
            BufferedReader in = new BufferedReader(new InputStreamReader(is));
            String temp = null;
            while ((temp = in.readLine()) != null) {
              System.out.println(temp);
            }
            is.close();
          }
          catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    }

    0
     
    LVL 24

    Expert Comment

    by:sciuriware
    You should always put I/O redirections at the end of a commandline as those should NOT be passed
    to the program. That would imply breaking the command line.
    Exception on this in the merge redirection in the UNIX shells:   command >output 2>&1

    So, retry with the < and >> at the end.
    ;JOOP!
    0
     
    LVL 12

    Expert Comment

    by:Giant2
    >...still it does not deal with input to the program which I achieve using "<" on the command line.

    In the link I post before:
    http://www.javaalmanac.com/egs/java.lang/Exec.html
    You can find this example:
    >...it is necessary to use the overload that requires the command and its arguments to be supplied in an array:
        try {
            // Execute a command with an argument that contains a space
            String[] commands = new String[]{"grep", "hello world", "/tmp/f.txt"};
            commands = new String[]{"grep", "hello world", "c:\\Documents and Settings\\f.txt"};
            Process child = Runtime.getRuntime().exec(commands);
        } catch (IOException e) {
        }

    Use this example with the parameters you want to use.
    Bye, Giant.
    0
     

    Author Comment

    by:avi_india
    Hi CEHJ/JOOP

    Both does not work!!!.. :(

    I have reached a point where I can execute one line using following code..


    ----------------------------------------------

    public class DataFields {
          public static void main(String argv[])
          {
                String command = "sqlplus -dsn sql -u user -p passwd"; // assume that this is correct

                try {
                      String line;
                
                      Process child = Runtime.getRuntime().exec(command);
                      BufferedReader input =
                                   new BufferedReader(new InputStreamReader(child.getInputStream()));
                               
                      
                     //   Get output stream to write from it
                      OutputStream out = child.getOutputStream();
                      
                      out.write("select * from tname;".getBytes());
                      // as soon as I add another out.write statement here - I start getting error
                      out.close();
                      
                      while ((line = input.readLine()) != null) {
                             System.out.println(line);
                      }
                      
                      input.close();
                }
                catch (Exception err) {
                     err.printStackTrace();
                }      
          }
    }

    ---------------------------------------------------------------------
    0
     
    LVL 92

    Expert Comment

    by:objects
    Use a PrintWriter for sending input:

    PrintWriter out = new PrintWiter(child.getOutputStream());
    out.println("select * from tname;");
    0
     
    LVL 92

    Expert Comment

    by:objects
    Here's a couple of examples of reading output from Process that can be easily modified to suit your needs:

    http://www.objects.com.au/java/examples/util/ConsoleExec.do
    http://www.objects.com.au/java/examples/util/SwingExec.do
    0
     
    LVL 86

    Expert Comment

    by:CEHJ
    The redirect in *could* be a problem. I know it works with redirect out, so try object's suggestion
    0
     
    LVL 11

    Expert Comment

    by:cjjclifford
    use the getOutputStream() as I suggested earlier... The reason I suggested the PrintWriter is that its easier to direct line seperated text...
    0
     
    LVL 86

    Expert Comment

    by:CEHJ
    >>use the getOutputStream() as I suggested earlier

    Sorry, cjclifford, i forgot you'd mentioned that earlier
    0
     
    LVL 11

    Expert Comment

    by:cjjclifford
    no problems :-)
    0
     
    LVL 11

    Expert Comment

    by:cjjclifford
    I missed yours and objects comments - really should refresh before adding comments more often :-)
    0
     

    Author Comment

    by:avi_india

    Nothing is actually working. I am able to execute only one statement. After that I have to re-execute, attach out & input streams again and then do the work. Can somebody please help me with execjuting statements again & again just as I do if I execute the program from command line.

    -Ajay
    0
     
    LVL 24

    Expert Comment

    by:sciuriware
    To do that contiuously you need to execute a shell and put your statements (=commands) on the
    standard output to this shell, another thread must read the output back.
    Note that this demand differs from your original question!
    ;JOOP!
    0
     

    Author Comment

    by:avi_india
    I understand that this is a bit different.. But how do i know that you can't put the above given solutions to work as in this way!!!!!!

    0
     
    LVL 11

    Assisted Solution

    by:cjjclifford
    ajay, I'm assuming you've put together 1) the two seperate threads (must be seperate threads!) for reading getInputStream() and getErrorStream(), and are using getOutputStream() to feed data to the standard input of the program executed: are you closing the output after each line? Closing the output stream results in the Standard Input to the executing program to close, which is generally a signal to close the application!

    did you read the link posted above by objects (http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html)?

    sciuriware, the author did include a redirect into the program being executed, so this can be seen as still on-question (of sorts!)
    0
     
    LVL 86

    Expert Comment

    by:CEHJ
    8-)
    0
     
    LVL 86

    Expert Comment

    by:CEHJ
    8-)
    0
     
    LVL 11

    Expert Comment

    by:cjjclifford
    thanks.
    0
     
    LVL 12

    Expert Comment

    by:Giant2
    :)
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone. Privacy Policy Terms of Use

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    Suggested Solutions

    Title # Comments Views Activity
    how to disable hibernate query cache 2 39
    Multiple issues with Java 14 32
    java ^ examples 8 40
    EvenOdd challenge 10 49
    For customizing the look of your lightweight component and making it look lucid like it was made of glass. Or: how to make your component more Apple-ish ;) This tip assumes your component to be of rectangular shape and completely opaque. (COD…
    Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
    This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
    This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

    877 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    12 Experts available now in Live!

    Get 1:1 Help Now