Java runtime.exe C ()

Source: Internet
Author: User
Let's start with the runtime class. It is a class related to the JVM runtime environment, which is Singleton. I want to talk about some things that I think are important to me.

1. runtime. getruntime () can obtain the runtime environment of the current JVM. This is the only method in Java to get the runtime environment.

2. Most of the other methods in runtime are instance methods. That is to say, the getruntime method is used for each runtime call.

3. The exit method in Runtime is the method for exiting the current JVM. It is estimated that it is the only method, because the exit method in the system class actually calls runtime. exit () to exit JVM. Here, we will describe the general rules of Java for the return value of Runtime (as mentioned later). 0 indicates normal exit, and non-0 indicates that the exception is aborted, this is only a Java rule, and there will always be some small obfuscation in each operating system.

4. The runtime. addshutdownhook () method can be used to register a hook. When the JVM executes shutdown, the method parameter can be a thread instance that has been initialized but has not been executed. (Note: it is not worthwhile to run all threads in Java)

5. When talking about addshutdownhook, we need to talk about the circumstances in which the JVM runtime environment is shut down or abort. The document is written in this way, when the last non-genie process exits or receives a User Interrupt signal, user logout, system shutdown, and runtime exit method is called, The JVM starts the shutdown process, after this process starts, it will start all the registered shutdown hooks in parallel (note that it is started in parallel, which requires thread security and prevention of deadlocks ). After the shutdown process is started, you can stop the shutdown process and exit JVM only by calling the halt method.

When will the JVM quit? The JVM stops running but does not necessarily shut down when abort exits. This occurs only when the JVM encounters an internal error such as an access to an invalid address, such as a sigkill signal, a Windows stop process signal, or a local method. In this case, the shutdown hook cannot be executed.

Now, read this article.

The first step is to reload all runtime.exe C () methods. One thing to note here is public process exec (string [] cmdarray, string [] envp). In this method, cmdarray is an array of executed commands and parameters, the first element of the array is that the command to be executed is followed by the command parameters. envp I personally think it should be the same as the environment variable in execve in C, in envp, name = value is used.

<! -- [If! Supportlists] --> 1. <! -- [Endif] --> A bad calling program. The Code is as follows. This program uses exec to call an external command and then uses exitvalue to check its return value immediately, let's see what will happen.

Import java. util .*;
Import java. Io .*;

Public class badexecjavac
{
Public static void main (string ARGs [])
{
Try
{
Runtime RT = runtime. getruntime ();
Process proc = rt.exe C ("javac ");
Int exitval = Proc. exitvalue ();
System. Out. println ("process exitvalue:" + exitval );
} Catch (throwable T)
{
T. printstacktrace ();
}
}
}

A run of badexecjavac produces:

E: classescomjavaworldjpitfallsarticle2> JAVA badexecjavac
Java. Lang. illegalthreadstateexception: process has not exited
At java. Lang. win32process. exitvalue (native method)
At badexecjavac. Main (badexecjavac. Java: 13)

You can see from the original article. The main problem here is that exitvalue is called incorrectly to obtain the returned value of an external command (I have also made this mistake ), the exitvalue method is non-blocking. When the program calls this method, external commands are not returned, causing an exception, here, another method is used to wait for the external command to be executed, that is, the waitfor method. This method will be blocked until the execution of the external command ends, and then return the execution result of the external command, the author has a problem with the idea of criticizing designers here. I don't have to worry about it. I can pull it if I can use it. However, the author has a note here that exitvalue also has many uses. Because when you call the waitfor method on a process, the current thread is blocked. If the external command cannot be executed, your thread will be blocked all the time, this accident will affect the execution of our program. So when we cannot determine when the external command is executed and our program still needs to be executed, we should use exitvalue cyclically to obtain the returned status of the external command, and handle the problem when the external command returns.

2. Improved programs for exitvalue

Import java. util .*;
Import java. Io .*;

Public class badexecjavac2
{
Public static void main (string ARGs [])
{
Try
{
Runtime RT = runtime. getruntime ();
Process proc = rt.exe C ("javac ");
Int exitval = Proc. waitfor ();
System. Out. println ("process exitvalue:" + exitval );
} Catch (throwable T)
{
T. printstacktrace ();
}
}
}

Unfortunately, this program cannot be executed, and it has no output but has been suspended. Why?

This is explained in the JDK document: because the local system is valid for the buffer pool provided by standard input and output, therefore, the rapid Writing of standard output and quick reading from standard input may cause sub-process locks or even deadlocks.

After the document was quoted, the author began to criticize it again. He said that JDK only explained why the problem occurred, but did not explain how to solve the problem. This is indeed a problem. Then the author tells us his practice, that is, after executing external commands, we need to control all input and output of process (depending on the situation ), in this example, because javac is called and the prompt information is output to the standard error Without parameters, we need to process this in the following program.

Import java. util .*;
Import java. Io .*;

Public class mediocreexecjavac
{
Public static void main (string ARGs [])
{
Try
{
Runtime RT = runtime. getruntime ();
Process proc = rt.exe C ("javac ");
Inputstream stderr = Proc. geterrorstream ();
Inputstreamreader ISR = new inputstreamreader (stderr );
Bufferedreader BR = new bufferedreader (ISR );
String line = NULL;
System. Out. println ("<error> ");
While (line = Br. Readline ())! = NULL)
System. Out. println (line );
System. Out. println ("</error> ");
Int exitval = Proc. waitfor ();
System. Out. println ("process exitvalue:" + exitval );
} Catch (throwable T)
{
T. printstacktrace ();
}
}
}

The running result of the program is

E: classescomjavaworldjpitfallsarticle2> JAVA mediocreexecjavac
<Error>
Usage: javac <Options> <source files>

Where <Options> Except des:
-G generate all debugging info
-G: none generate no debugging info
-G: {lines, vars, source} generate only some debugging info
-O optimize; may hinder debugging or enlarge class files
-Nowarn generate no warnings
-Verbose output messages about what the compiler is doing
-Deprecation output source locations where Deprecated APIs are used
-Classpath <path> specify where to find user class files
-Sourcepath <path> specify where to find input source files
-Bootclasspath <path> override location of Bootstrap class files
-Extdirs <dirs> override location of installed extensions
-D <directory> specify where to place generated class files
-Encoding <encoding> specify character encoding used by source files
-Target <release> Generate class files for specific VM version
</Error>
Process exitvalue: 2

Ah, no matter what the results are, the author makes a summary, that is, to handle a large number of output External commands, make sure that your program processes the input or output required by external commands.

Next question: an error that is easy to make when we call a program that we think is executable (I just made this mistake this evening and there is nothing to do with this exercise)

Import java. util .*;
Import java. Io .*;

Public class badexecwindir
{
Public static void main (string ARGs [])
{
Try
{
Runtime RT = runtime. getruntime ();
Process proc = rt.exe C ("dir ");
Inputstream stdin = Proc. getinputstream ();
Inputstreamreader ISR = new inputstreamreader (stdin );
Bufferedreader BR = new bufferedreader (ISR );
String line = NULL;
System. Out. println ("<output> ");
While (line = Br. Readline ())! = NULL)
System. Out. println (line );
System. Out. println ("</output> ");
Int exitval = Proc. waitfor ();
System. Out. println ("process exitvalue:" + exitval );
} Catch (throwable T)
{
T. printstacktrace ();
}
}
}

A run of badexecwindir produces:

E: classescomjavaworldjpitfallsarticle2> JAVA badexecwindir
Java. Io. ioexception: CreateProcess: Dir error = 2
At java. Lang. win32process. Create (native method)
At java. Lang. win32process. <init> (unknown source)
At java.lang.runtime.exe cinternal (native method)
At java.lang.runtime.exe C (unknown source)
At java.lang.runtime.exe C (unknown source)
At java.lang.runtime.exe C (unknown source)
At java.lang.runtime.exe C (unknown source)
At badexecwindir. Main (badexecwindir. Java: 12)

To be honest, this error is really confusing to me. I think the result of returning 2 in Windows is that the file is not found. Maybe Windows 2000 only has the CMD command, the dir command cannot be explained by the current environment variable. I don't know. Let's take a look.

Because the file does not find this 2 error. If we want to execute such a command, we need to first execute different explain programs command.com according to different operating systems.

The author modified the above program.

Import java. util .*;
Import java. Io .*;

Class streamgobbler extends thread
{
Inputstream is;
String type;

Streamgobbler (inputstream is, string type)
{
This. Is = is;
This. type = type;
}

Public void run ()
{
Try
{
Inputstreamreader ISR = new inputstreamreader (is );
Bufferedreader BR = new bufferedreader (ISR );
String line = NULL;
While (line = Br. Readline ())! = NULL)
System. Out. println (Type + ">" + line );
} Catch (ioexception IOE)
{
IOE. printstacktrace ();
}
}
}

Public class goodwindowsexec
{
Public static void main (string ARGs [])
{
If (ARGs. Length <1)
{
System. Out. println ("Usage: Java goodwindowsexec <cmd> ");
System. Exit (1 );
}

Try
{
String osname = system. getproperty ("OS. Name ");
String [] cmd = new string [3];

If (osname. Equals ("Windows NT "))
{
CMD [0] = "cmd.exe ";
CMD [1] = "/C ";
CMD [2] = ARGs [0];
}
Else if (osname. Equals ("Windows 95 "))
{
CMD [0] = "command.com ";
CMD [1] = "/C ";
CMD [2] = ARGs [0];
}

Runtime RT = runtime. getruntime ();
System. Out. println ("execing" + cmd [0] + "" + cmd [1]
+ "" + Cmd [2]);
Process proc = rt.exe C (CMD );
// Any error message?
Streamgobbler errorgobbler = new
Streamgobbler (Proc. geterrorstream (), "error ");

// Any output?
Streamgobbler outputgobbler = new
Streamgobbler (Proc. getinputstream (), "output ");

// Kick them off
Errorgobbler. Start ();
Outputgobbler. Start ();

// Any error ???
Int exitval = Proc. waitfor ();
System. Out. println ("exitvalue:" + exitval );
} Catch (throwable T)
{
T. printstacktrace ();
}
}
}

Running goodwindowsexec with the Dir command generates:

E: classescomjavaworldjpitfallsarticle2> JAVA goodwindowsexec "dir *. Java"
Execing cmd.exe/C dir *. Java
Output> volume in drive E has no label.
Output> volume serial number is 5c5f-0cc9
Output>
Output> directory of E: classescomjavaworldjpitfallsarticle2
Output>
Output> 10/23/00 09: 01 P 805 badexecbrowser. Java
Output> 10/22/00 09: 35a 770 badexecbrowser1.java
Output> 10/24/00 08: 45 p 488 badexecjavac. Java
Output> 10/24/00 08: 46 P 519 badexecjavac2.java
Output> 10/24/00 09: 13 p 930 badexecwindir. Java
Output> 10/22/00 09: 21a 2,282 badurlpost. Java
Output> 10/22/00 09: 20a 2,273 badurlpost1.java
... (Some output omitted for brespon)
Output> 10/12/00 09: 29 p 151 superframe. Java
Output> 10/24/00 09: 23 p 1,814 testexec. Java
Output> 10/09/00 05: 47 P 23,543 teststringreplace. Java
Output> 10/12/00 08: 55 p 228 toplevel. Java
Output> 22 file (s) 46,661 bytes
Output & gt; 19,678,420,992 bytes free
Exitvalue: 0

Here, the author taught a very useful example in windows, in the same go, I do not know, just register the file name with a Suffix in windows. Windows will automatically call the relevant program to open this document, I tried it, it is indeed very useful, however, it seems that there are spaces in the file path, which cannot be solved by adding quotation marks.

The author emphasizes that it is important not to assume that the program you run is an executable program, but whether your program is separately executable or interpreted, the end of this chapter will introduce a command line tool to help us analyze it.

Another point here is that getinputstream is used to get the output of process, because from the Java program perspective, the output of external programs is input for Java, and vice versa.

The last vulnerability is that the exec method is incorrectly considered to accept all strings you input and accept in the command line or shell. These errors mainly occur when the command is used as a parameter. The programmer mistakenly adds the parameter commands that can be entered in all command lines to Exec (this translation is not good, let's take a look ). In the following example, a programmer wants to redirect the output of a command.

Import java. util .*;
Import java. Io .*;

// Streamgobbler omitted for breted

Public class badwinredirect
{
Public static void main (string ARGs [])
{
Try
{
Runtime RT = runtime. getruntime ();
Process proc = rt.exe C ("Java jecho 'Hello world'> test.txt ");
// Any error message?
Streamgobbler errorgobbler = new
Streamgobbler (Proc. geterrorstream (), "error ");

// Any output?
Streamgobbler outputgobbler = new
Streamgobbler (Proc. getinputstream (), "output ");

// Kick them off
Errorgobbler. Start ();
Outputgobbler. Start ();

// Any error ???
Int exitval = Proc. waitfor ();
System. Out. println ("exitvalue:" + exitval );
} Catch (throwable T)
{
T. printstacktrace ();
}
}
}

Running badwinredirect produces:

E: classescomjavaworldjpitfallsarticle2> JAVA badwinredirect
Output> 'Hello world'> test.txt
Exitvalue: 0

The programmer's intention is to rewrite the hello World input to a text file, but this file is not generated. jecho only outputs parameters in the command line to the standard output, the user thinks that the output can be redirected to a file like DOS, but this cannot be implemented. The user mistakenly regards Exec As a shell interpreter, but it is not, if you want to redirect the output of a program to another program, you must use the program to implement it. Packages in Java. Io are available.

Import java. util .*;
Import java. Io .*;

Class streamgobbler extends thread
{
Inputstream is;
String type;
Outputstream OS;

Streamgobbler (inputstream is, string type)
{
This (is, type, null );
}

Streamgobbler (inputstream is, string type, outputstream redirect)
{
This. Is = is;
This. type = type;
This. OS = redirect;
}

Public void run ()
{
Try
{
Printwriter PW = NULL;
If (OS! = NULL)
PW = new printwriter (OS );

Inputstreamreader ISR = new inputstreamreader (is );
Bufferedreader BR = new bufferedreader (ISR );
String line = NULL;
While (line = Br. Readline ())! = NULL)
{
If (PW! = NULL)
PW. println (line );
System. Out. println (Type + ">" + line );
}
If (PW! = NULL)
PW. Flush ();
} Catch (ioexception IOE)
{
IOE. printstacktrace ();
}
}
}

Public class goodwinredirect
{
Public static void main (string ARGs [])
{
If (ARGs. Length <1)
{
System. Out. println ("usage Java goodwinredirect <outputfile> ");
System. Exit (1 );
}

Try
{
Fileoutputstream Fos = new fileoutputstream (ARGs [0]);
Runtime RT = runtime. getruntime ();
Process proc = rt.exe C ("Java jecho 'Hello world '");
// Any error message?
Streamgobbler errorgobbler = new
Streamgobbler (Proc. geterrorstream (), "error ");

// Any output?
Streamgobbler outputgobbler = new
Streamgobbler (Proc. getinputstream (), "output", FOS );

// Kick them off
Errorgobbler. Start ();
Outputgobbler. Start ();

// Any error ???
Int exitval = Proc. waitfor ();
System. Out. println ("exitvalue:" + exitval );
FOS. Flush ();
FOS. Close ();
} Catch (throwable T)
{
T. printstacktrace ();
}
}
}

Running goodwinredirect produces:

E: classescomjavaworldjpitfallsarticle2> JAVA goodwinredirect test.txt
Output> 'Hello world'
Exitvalue: 0

I will not talk about it here. Let's take a look. Then the author gives a small program for monitoring commands.

Import java. util .*;
Import java. Io .*;

// Class streamgobbler omitted for breted

Public class testexec
{
Public static void main (string ARGs [])
{
If (ARGs. Length <1)
{
System. Out. println ("Usage: Java testexec" cmd "");
System. Exit (1 );
}

Try
{
String cmd = ARGs [0];
Runtime RT = runtime. getruntime ();
Process proc = rt.exe C (CMD );

// Any error message?
Streamgobbler errorgobbler = new
Streamgobbler (Proc. geterrorstream (), "Err ");

// Any output?
Streamgobbler outputgobbler = new
Streamgobbler (Proc. getinputstream (), "out ");

// Kick them off
Errorgobbler. Start ();
Outputgobbler. Start ();

// Any error ???
Int exitval = Proc. waitfor ();
System. Out. println ("exitvalue:" + exitval );
} Catch (throwable T)
{
T. printstacktrace ();
}
}
}

Run this program:
E: classescomjavaworldjpitfallsarticle2> JAVA testexec "E: javadocsindex.html"
Java. Io. ioexception: CreateProcess: e: javadocsindex.html error = 193
At java. Lang. win32process. Create (native method)
At java. Lang. win32process. <init> (unknown source)
At java.lang.runtime.exe cinternal (native method)
At java.lang.runtime.exe C (unknown source)
At java.lang.runtime.exe C (unknown source)
At java.lang.runtime.exe C (unknown source)
At java.lang.runtime.exe C (unknown source)
At testexec. Main (testexec. Java: 45)

193 in windows, this is not a Win32 program. This indicates that the associated program of this webpage cannot be found in the path. The author decides to use an absolute path to try it out.

E: classescomjavaworldjpitfallsarticle2> JAVA testexec
"E: Program filesnetscapeprogramnetscape.exe E: javadocsindex.html"
Exitvalue: 0

I tried it again. I used IE.

Finally, the author sums up several rules to prevent errors when calling runtime.exe C.

<! -- [If! Supportlists] --> 1. <! -- [Endif] --> you cannot get the exit status of an external process before it is executed.

<! -- [If! Supportlists] --> 2. <! -- [Endif] --> when your external program starts execution, you must control the input, output, and error streams immediately.

<! -- [If! Supportlists] --> 3. <! -- [Endif] --> you must use runtime.exe C () to execute the program.

<! -- [If! Supportlists] --> 4, <! -- [Endif] --> you cannot use runtime.exe C () as a command line ().

 

 

 

 

From: http://kuangbaoxu.iteye.com/blog/210291

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.