Java Runtime Execution System command-line program

Source: Internet
Author: User

Previously wrote an article about executing operating system command-line programs through the Java Runtime class: Java calls the Linux system Shell to execute commands. In recent projects, there is a need to use this method, in the use of the process encountered some new problems, the feeling has not been clear before, so do a supplementary study record here.

Let's start by explaining this requirement, controlling the Hadoop command in a Java program to execute a MapReduce job and get its output. There was nothing special, but because Mr performs the Kmeans algorithm, it produces multiple Mr Programs recursively, and when the output is captured there is only a few simple hints and no details of the Mr Job.
After the query, it is found that some of the information in the execution process is output as general information, and the other part is output as debug information. For example, use the red line to circle out a normal output (only this line is captured), the other is the debug information.

         in order to distinguish between these two kinds of information, it is necessary to say the Runtime this thing. The explanation for this class in the Java API is the public class Java.lang.Runtime extends Java.lang.Object.
         Each Java application has a runtime class instance that enables the application to connect to the environment in which it is running. The current runtime can be obtained through the GetRuntime method. The application cannot create its own instance of the Runtime class. As you can see in the API documentation, after executing a command, the system returns a new process object for managing the child process. So, this new Process object is what, continue to see the API, public abstract class Java.lang.Process extends Java.lang.Object. The instance can be used to control the process and obtain relevant information.
         Also, the process class provides execution from process input, execution output to process, waiting for process completion, Check the exit status of the process and how to destroy (kill) the process.
         all of its standard IO (i.e., stdin, stdout, and STDERR) operations will pass through three streams (Getoutputstream (), getInputStream () and Geterrorstream ()) are redirected to the parent process. The
         parent process uses these streams to provide input to child processes and to derive output from child processes. Because some native platforms only provide a limited buffer size for standard input and output streams, it can cause child processes to block and even deadlock if the output stream or input stream of a child process fails quickly.

         Now the problem is obvious. Previously, only the InputStream object of Process.getinputstream () was obtained, and no data was sent by using Process.geterrorstream () to get the error output of the process.
         originally wanted to output two streams of data through a while loop, but found that the Process was read with BufferedReader When stream flows, when the stream is empty (not yet created, not null), then the BufferedReader is blocked.
         So think about it or you have to use the multi-threaded way to output the contents of two streams at the same time.
         So, the code updates, it becomes the way it is.

package Com.cz.shell;import java.io.bufferedreader;import Java.io.inputstreamreader;class CzStreamOutput extends Thread { Public BufferedReader br;public Czstreamoutput () {}public czstreamoutput (BufferedReader br) {this.br = BR;} public void Run () {String Line;try {when (line = Br.readline ())! = null) {SYSTEM.OUT.PRINTLN (line)}} catch (Exception E ) {e.printstacktrace ();}}} public class Czshell {public static void Runshell (String cmd) throws Exception {Process Process = null;try {process = Runt Ime.getruntime (). exec (CMD); BufferedReader bri = new BufferedReader (New InputStreamReader (Process.getinputstream ())); BufferedReader bre = new BufferedReader (New InputStreamReader (Process.geterrorstream ())); New Czstreamoutput (BRI). Start (); New Czstreamoutput (BRE). Start ();p rocess.waitfor (); Bri.close (); Bre.close (); catch (Exception e) {e.printstacktrace ();} finally {Process.destroy ();}}} 

         Run tests on Linux (Centos 6.2), everything goes well. However, in this case, because it is multi-threading, in theory there will be some error flow and output stream order reversal, but for most of the command, the system always frequency than the command execution when the interval between two streams is much higher, the likelihood of confusion is very small.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.