?
Solved

Runtime.getRuntime().exec(cmd) Problem

Posted on 2002-07-01
7
Medium Priority
?
3,710 Views
Last Modified: 2013-11-18
/*
JDK1.3.1 / Oracle8.1.6 / Windows 2000

[1]. I want to do export of a user database, then create a new user in oracle and then import the exported database into this new user and finally run a .sql script on this new user database to update it. That is 4 STEPS. All these steps I want to perform from within my java program. I wrote following program to export the scott/tiger database into a file using "Runtime.getRuntime().exec(cmd);" but this program hangs at a point "starting...". What is wrong here?

[2]. Does oracle provide some internal packages for doing these operations in better way. If it does then what are those procedures that I could call from JDBC CallableStatement. I just don't want to rely on "Runtime.getRuntime().exec(cmd);"
*/

import java.io.*;

class Exec {  
    public static void main(String[] args) throws IOException {
        // Get the command
        String cmd;
        if (args.length == 0) {
            cmd = "exp scott/tiger buffer=4096 file=C:\\temp\\scott.dmp";
        }
        else {
            cmd = args[0];
        }
           
        // Execute command
        Runtime runtime = Runtime.getRuntime();
        Process pr = runtime.exec(cmd);

        // Print command output onto standard output
        InputStream is = pr.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String str;
        System.out.println("starting...");
        while ((str = br.readLine()) != null) {
            System.out.println(str);
        }
        is.close();
        System.out.println("over...");

        // Wait for the process to complete.
        int status = -1;
        System.out.println("waiting starts");
        try {
            status = pr.waitFor();
        }
        catch (InterruptedException e) {
            System.out.println(e);
        }
        System.out.println("waiting over");
    }
}
0
Comment
Question by:javaq092999
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 9

Accepted Solution

by:
Ovi earned 200 total points
ID: 7123798
1.       System.out.println("starting...");
        while ((str = br.readLine()) != null) {
            System.out.println(str);
        }
Your code is blocked here in the while statement and you don't receive any information on the inputStream (your command does not write anything). Remember that you can obtain from a process 3 streams : 2 inputStreams ( the process outputstream which is an input stream for your application and the error stream) and a outputStream which is the outputstream for your application and inputstream for the proccess. In your current implementation you only can read from the inputstream (proccess out) which will block totally your application, until the external process quits.

Try to modify this example to fit your needs.
import java.io.*;

public class RuntimeTest {

  public static void main(String args[]) {
    try{
      Runtime rt = Runtime.getRuntime();

      final Process p = rt.exec("/usr/lib/jdk1.4.0/bin/javac Top.java");
        new Thread(new Runnable() {
       public void run() {
            try {
              BufferedReader br_in = new BufferedReader(new InputStreamReader(p.getInputStream()));
              String buff = null;
              while ((buff = br_in.readLine()) != null) {
             System.out.println("Process out :" + buff);
             try {Thread.sleep(100); } catch(Exception e) {}
           }
              br_in.close();
            } catch (IOException ioe) {
              System.out.println("Exception caught printing javac result");
              ioe.printStackTrace();
            }
       }
     }).start();

        new Thread(new Runnable() {
       public void run() {
            try {
              BufferedReader br_err = new BufferedReader(new InputStreamReader(p.getErrorStream()));
              String buff = null;
              while ((buff = br_err.readLine()) != null) {
                   System.out.println("Process err :" + buff);
             try {Thread.sleep(100); } catch(Exception e) {}
           }
              br_err.close();
            } catch (IOException ioe) {
              System.out.println("Exception caught printing javac result");
              ioe.printStackTrace();
            }
       }
     }).start();
    } catch (Exception e) {
      System.out.println("Exception");
      e.printStackTrace();
    }
  }
}


2. I don't know, perhaps you should ask to oracle topic in this site.
0
 
LVL 3

Expert Comment

by:mjzalewski
ID: 7125556
The solution proposed has one small problem.

The main thread does not wait for completion of the command. Works well for running a single command. But javag wants to exp a database then imp to a new user. The imp must wait for the exp to finish.

This doesn't mean that the task to be executed will be interrupted. It just means that the method main() will complete before the Process object does.

I think you need to join the two worker threads you created to handle the Process object's output. By join I mean call the thread objects join() method from main().

Of course, the short solution is to put all four commands into a batch file (or shell script), then just execute the script.
0
 
LVL 9

Expert Comment

by:Ovi
ID: 7125926
mjzalewski : "... Try to modify this example to fit your needs. ..." - is the statement right above my code. Did you ever test my program? I believe not if I read again your comment. The program will exit only when the streams are closed, because the threads are blocked in waiting for input. Here is a modified version which prints messages when enters and exit's from the main method. After exit from main you will see the results of the command. But anyway, the proposed program is an exemplification of how to handle external commands (in this case it tries to compile a file called Top.java). I will post the Top.java source also, is a short one, filled with errors, so my threads have something to read. For windows systems there should be modified the path to the java compiler.

import java.io.*;

public class RuntimeTest {

  public static void main(String args[]) {
    System.out.println("Entering main method ....");
    try{
      Runtime rt = Runtime.getRuntime();

      final Process p = rt.exec("/usr/lib/jdk1.4.0/bin/javac Top.java");
        new Thread(new Runnable() {
       public void run() {
            try {
              BufferedReader br_in = new BufferedReader(new InputStreamReader(p.getInputStream()));
              String buff = null;
              while ((buff = br_in.readLine()) != null) {
             System.out.println("Process out :" + buff);
             try {Thread.sleep(100); } catch(Exception e) {}
           }
              br_in.close();
            } catch (IOException ioe) {
              System.out.println("Exception caught printing javac result");
              ioe.printStackTrace();
            }
       }
     }).start();
     
        new Thread(new Runnable() {
       public void run() {
            try {
              BufferedReader br_err = new BufferedReader(new InputStreamReader(p.getErrorStream()));
              String buff = null;
              while ((buff = br_err.readLine()) != null) {
                   System.out.println("Process err :" + buff);
             try {Thread.sleep(100); } catch(Exception e) {}
           }
              br_err.close();
            } catch (IOException ioe) {
              System.out.println("Exception caught printing javac result");
              ioe.printStackTrace();
            }
       }
     }).start();
    } catch (Exception e) {
      System.out.println("Exception");
      e.printStackTrace();
    }
    System.out.println("Exiting main method .... Done!");
  }
}

//Top.java
class Top {
 void methodwitherrors(){
   System.out.prin();
 }
}    
0
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 
LVL 92

Expert Comment

by:objects
ID: 7126442
Try simply changing:

InputStream is = pr.getInputStream();


to:

InputStream is = pr.getErrorStream();
0
 

Author Comment

by:javaq092999
ID: 7137607
Thanks Ovi and all
0
 
LVL 9

Expert Comment

by:Ovi
ID: 7139705
me too -:)
0
 

Expert Comment

by:akirekadu
ID: 7622721

I observed that "WMIC" command hangs when invoked with Runtime.exec().  (WMIC is the WMI command line utility that comes with MS WMI toolkit)

Does anybody know what is special with WMIC?

Here's the code
--------------
Runtime runtime = Runtime.getRuntime();
String commands[] = new String[2];
commands[0] = "wmic";
commands[1]="/?";
Process proc = runtime.exec(commands);
ProcStreamReader stdoutReader =
     new ProcStreamReader(proc.getInputStream());
ProcStreamReader stderrReader =
     new ProcStreamReader(proc.getErrorStream());
stdoutReader.start();
stderrReader.start();
int returnCode = proc.waitFor();
System.out.println(stdoutReader.getData());
---------------------

public class ProcStreamReader extends Thread {    
     private InputStream in;
     private StringBuffer data;
     public ProcStreamReader(InputStream argIn) {
          in = argIn;
          data = new StringBuffer();
     }
     
     public void run() {
          try {
               BufferedReader reader = new BufferedReader(
                    new InputStreamReader(in));
               String line = null;
               
               while( (line = reader.readLine()) != null) {
                    data.append(line);
               }
          } catch(IOException ioe) {
               ioe.printStackTrace();
          }
         
     }
     public String getData() {
          return data.toString();
     }    

}
------------

Ashwath Akirekadu
PANACYA Inc
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

SASS allows you to treat your CSS code in a more OOP way. Let's have a look on how you can structure your code in order for it to be easily maintained and reused.
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will receive an overview of the basics of CSS showing inline styles. In the head tags set up your style tags: (CODE) Reference the nav tag and set your properties.: (CODE) Set the reference for the UL element and styles for it to ensu…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses
Course of the Month12 days, 6 hours left to enroll

752 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