When my Java program is halted abnormally, applications started by Runtime.exec() do not stop. How do I stop these applications?
Process process = null;
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable()
{
public void run() {
process.destroy();
}
}));
try
{
process = Runtime.getRuntime().exec("win.exe");
process.waitFor();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
process.destroy();
}
addShutdownHook does not execute on forced shutdown of Java such as:
killing from Task Manager
killing via Eclipse Stop button
kill -9 on Linux.
It does execute when using
Ctrl+c
other user initiated interruptions such as Windows shutdown.
kill on Linux
You can test this by compiling your Java file into a class file, then running on the command line. After running on the command line, you can press Ctrl+c to observe that the shutdown hook is executed.
To test, create RunTimeTest.java as shown below, then compile using your JDK.
For example:
"c:\Program Files\Java\jdk1.7.0_40\bin"\javac RunTimeTest.java
"c:\Program Files\Java\jdk1.7.0_40\bin"\java RunTimeTest
Test code:
import java.io.IOException;
import java.util.Arrays;
public class RunTimeTest {
public static void main(String arguments[]) {
ProcessBuilder processBuilder = new ProcessBuilder(Arrays.asList("notepad.exe"));
Process process = null;
try {
process = processBuilder.start();
final Process processToKill = process;
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Shutdown Hook");
processToKill.destroy();
}
}));
process.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
} finally {
if (process != null) {
System.out.println("End of try");
process.destroy();
}
}
}
}
See Javadoc for Runtime
Worst case scenario: if you are using the program multiple times, in the next run you can kill that process.
String command = "cmd /c taskkill /f /im win.exe";
Runtime.getRuntime().exec(command);
Related
I have a Java program with an attached shutdown hook. I run it and after I kill the running process with kill <PID>. By doing this the shutdown hook got executed and the related threads stopped immediately. But the process is still running in the background. So what could be the problem here?
Process:
javac InfiniteLoop.java
java InfiniteLoop
For PID, jps -ml | grep 'InfiniteLoop'
kill <PID>
public class InfiniteLoop {
static boolean isInfinte = true;
public static void main(String[] args) throws InterruptedException {
Thread myThread = new MyShutDownHook();
Runtime.getRuntime().addShutdownHook(myThread);
while (isInfinte) {
Thread.sleep(3000);
System.out.println("Loop is running");
}
System.out.println("Loop Exited");
myThread.interrupt();
}
}
class MyShutDownHook extends Thread {
#Override
public void run() {
System.out.print("Got Kill Message so stopping application");
InfiniteLoop.isInfinte = false;
boolean currentLoopStatus = true;
while (currentLoopStatus) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.print("Got Intteruption");
currentLoopStatus = false;
e.printStackTrace();
System.exit(0);
}
System.out.println("Child Thread Running");
}
}
}
You have used System.exit(0) in your shutdown hook thread. Remove it shutdown hook so that the process would get terminated normally. Actually System.exit(0) itself calls shutdown internally so it could possible that code is in deadlock.
I want launch a batch file with JAVA. So I create a shortcut to this file and config Run as Administrator. I tested the batch file and it run success. But when, I run it with java, the batch file don't run with Administrator and the request is denied.
In java source, I try to call a shortcut of cmd.exe with shortcut configed Run as Administrator. And java source open the commandline with Administrator success.
Please help me.
Here my code:
package testfp;
import java.io.*;
public class RunCommand {
String command,result;
public RunCommand(String command) {
this.command = command;
run();
System.out.println(this.result);
}
public void run() {
try
{
Process process = Runtime.getRuntime().exec("cmd /c start C:\\Users\\minhlc\\Desktop\\test\\CMD");
// Fail to open with Administrator
// Process process = Runtime.getRuntime().exec("cmd /c start C:\\Users\\minhlc\\Desktop\\test\\start_apache");
// process.destroy();
// Process process = Runtime.getRuntime().exec("cmd /c start");
// kill_process();
BufferedReader br = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
try {
while ((line = br.readLine()) != null) {
this.result = this.result + "\n" + line;
}
} finally {
// br.close();
};
} catch (IOException e)
{
e.printStackTrace();
}
}
public void kill_process()
{
try {
Runtime.getRuntime().exec("taskkill /f /im cmd.exe") ;
} catch (Exception e) {
e.printStackTrace();
}
}
public String get_result() {
return result;
}
}
Thank for reading.
You need to run the java process with an administration privilege.
Open command line with "Run as administrator" and then
java -jar you_app.jar
Please know that stanford is not exe. it is a folder consists many programs
I open the cmd.exe by using following statement:
public static void runStanfordCMD() throws IOException{
List<String> cmds = Arrays.asList("cmd.exe", "/C", "start", "java", "-mx4g", "-cp", "*", "edu.stanford.nlp.pipeline.StanfordCoreNLPServer");
ProcessBuilder builder = new ProcessBuilder(cmds);
builder.directory(new File("D:/Desktop/stanford-corenlp-full-2015-12-09"));
Process proc = builder.start();
}
so how to close the cmd.exe after I finished some process?
by using ProcessBuilder or Runtime?
If using ProcessBuilder how to write the statement according to my case?
how to write the statement to the Runtime according to my case?
public static void closeStanfordCMD() throws IOException{
try {
Runtime.getRuntime().exec("command.exe /C" + "Your command"); // how to write the statement?
} catch (Exception e) {
e.printStackTrace();
}
}
The method
Runtime.getRuntime().exec
returns an object of Process.
Process has a method destroy() which kills the process you're running.
So what you need is to store the Process object returned by the exec method and call destroy() on it when you want to kill the process.
Also you can call waitFor() method to wait for the process to stop (Causes the current thread to wait, if necessary, until the process represented by this Process object has terminated).
To make it clear, try this code (or modify for your needs):
try {
Process p = Runtime.getRuntime().exec("java -mx4g -cp * D:/Desktop/stanford-corenlp-full-2015-12-09/edu.stanford.nlp.pipeline.StanfordCoreNLPServer");
p.waitFor();
}
catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
// how to write the statement?
if you want to close command prompt:
Runtime.getRuntime().exec("taskkill /IM " + "cmd.exe");
if you want to close stanford.exe:
Runtime.getRuntime().exec("taskkill /IM " + "stanford.exe");
I wrote a process manager program one of the things that it does is to exit all running processes when it shut down
,so there is the code
public void stop_all() throws IOException {
Process p = Runtime.getRuntime().exec("kill -9 -1");
System.out.println("killed");
}
and there is the action on the button
private void exitButton(java.awt.event.ActionEvent evt) {
Run ob = new Run();
try {
ob.stop_all();
} catch (IOException ex) {
Logger.getLogger(mainmenu.class.getName()).log(Level.SEVERE, null, ex);
}
this.dispose();
}
i have no idea why it doesn't work ,
i execute that command in the terminal and it works fine
please help :)
I am still skeptical about the permissions of the program. But, from this reference you need to specify the command path in your exec().
So your code should probably be:
public void stop_all() throws IOException {
Process p = Runtime.getRuntime().exec("/bin/kill -9 -1");
System.out.println("killed");
}
I am trying to run an accurev command using Java Runtime exec (as described in code below). Since I have a network problem so when the login command is executed the command keeps on waiting for the response and doesn't time out. So how should I be able handle this error.
private static void accurevLogin() throws IOException {
Runtime runTime = Runtime.getRuntime();
String userName = prop.getProperty("UserName");
String password = prop.getProperty("Password");
String command = (new StringBuilder("accurev login ")).append(userName).append(" ").append(password).toString();
Process ps = null;
try {
ps = runTime.exec(command);
} catch (IOException e) {
System.out.println("Command Execution Error!");
}
/* Error handling Code */
System.out.println("ACCUREV LOGGED IN");
}
When I use
BufferedReader input = new BufferedReader(new InputStreamReader(ps.getInputStream()));
input.readline in the loop will keep on running and I am not able to check the output.
The best way would be to use a timeout option of the accurev command, if available.
If there is no such option, you should execute it in a seperate Java thread and abort programatically after some timeout of your choosing.
Here is an example with a simple sleep command:
Thread thread = new Thread() {
public void run() {
try {
Process proc = Runtime.getRuntime().exec("sleep 5");
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread.start(); //start thread in background
synchronized (thread) {
try {
thread.wait(1000L); //your timeout
if (thread.isAlive()) {
System.out.println("interrupting");
thread.interrupt(); //interrupt the thread
}
} catch (Exception e) {
System.out.println("interrupted");
}
}