FULL PRODUCT VERSION :
java version "1.5.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_01-b08)
Java HotSpot(TM) Client VM (build 1.5.0_01-b08, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
Process.waitFor() does not does not clear the interrupt status of the current thread when the InterruptedException is thrown. The documentation does not specify that the status of the interrupt bit for the current thread when this exception is thrown.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The test case is designed to simulate a user performing a ExecutorService.shutdownNow(). The java app is suppose to clean up any process that it spawned and any data file created by java but viewed using spawned process. In order to do that, the spawn process must be destroyed first so the File.delete() or File.deleteOnExit() from java does not fail (omitted from test). The external process does not release its file lock until Process.waitFor() returns a value.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
[C:\Program, Files\Microsoft, Office\OFFICE11\excel.exe]
Type=java.lang.ProcessImpl
interrupted=false
Type=java.lang.ProcessImpl
interrupted=false
1
1
ACTUAL -
[C:\Program, Files\Microsoft, Office\OFFICE11\excel.exe]
Type=java.lang.ProcessImpl
interrupted=true
java.lang.InterruptedException
at java.lang.ProcessImpl.waitFor(Native Method)
at ProcessTest.run(ProcessTest.java:21)
at java.lang.Thread.run(Thread.java:595)
-57
Type=java.lang.ProcessImpl
interrupted=true
java.lang.InterruptedException
at java.lang.ProcessImpl.waitFor(Native Method)
at ProcessTest.run(ProcessTest.java:21)
at java.lang.Thread.run(Thread.java:595)
-57
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.IOException;
public class ProcessTest implements Runnable {
private final Process p;
public ProcessTest(final Process p) {
this.p = p;
}
public void run() {
System.out.println("Type="+ p.getClass().getName());
int exitValue = -57;
try {
try {
exitValue = p.waitFor();
}
catch(final InterruptedException IE) { //user cancel
//System.out.println("interrupted="+ Thread.interrupted());
System.out.println("interrupted="+ Thread.currentThread().isInterrupted());
p.destroy();
exitValue = p.waitFor();
}
}
catch(InterruptedException IE) { //should not happen
IE.printStackTrace(System.out);
}
finally {
System.out.println(exitValue);
}
}
public static void main(String[] args) {
if(args.length > 0) {
System.out.println(java.util.Arrays.toString(args));
try {
final Thread rt = startViaRt(args);
final Thread pb = startViaPb(args);
rt.start();
pb.start();
rt.interrupt(); //signal shutdown
pb.interrupt();
}
catch(IOException IOE) {
IOE.printStackTrace();
}
}
else {
System.out.println("Must supply an external process.");
}
}
private static Thread startViaRt(final String[] args) throws IOException {
final ProcessTest monitor = new ProcessTest(Runtime.getRuntime().exec(args));
final Thread t = new Thread(monitor);
return t;
}
private static Thread startViaPb(final String[] args) throws IOException {
final ProcessBuilder pb = new ProcessBuilder(args);
final ProcessTest monitor = new ProcessTest(pb.start());
final Thread t = new Thread(monitor);
return t;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Call Thread.interrupted() to clear the interrupt status in the catch block.
java version "1.5.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_01-b08)
Java HotSpot(TM) Client VM (build 1.5.0_01-b08, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
Process.waitFor() does not does not clear the interrupt status of the current thread when the InterruptedException is thrown. The documentation does not specify that the status of the interrupt bit for the current thread when this exception is thrown.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The test case is designed to simulate a user performing a ExecutorService.shutdownNow(). The java app is suppose to clean up any process that it spawned and any data file created by java but viewed using spawned process. In order to do that, the spawn process must be destroyed first so the File.delete() or File.deleteOnExit() from java does not fail (omitted from test). The external process does not release its file lock until Process.waitFor() returns a value.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
[C:\Program, Files\Microsoft, Office\OFFICE11\excel.exe]
Type=java.lang.ProcessImpl
interrupted=false
Type=java.lang.ProcessImpl
interrupted=false
1
1
ACTUAL -
[C:\Program, Files\Microsoft, Office\OFFICE11\excel.exe]
Type=java.lang.ProcessImpl
interrupted=true
java.lang.InterruptedException
at java.lang.ProcessImpl.waitFor(Native Method)
at ProcessTest.run(ProcessTest.java:21)
at java.lang.Thread.run(Thread.java:595)
-57
Type=java.lang.ProcessImpl
interrupted=true
java.lang.InterruptedException
at java.lang.ProcessImpl.waitFor(Native Method)
at ProcessTest.run(ProcessTest.java:21)
at java.lang.Thread.run(Thread.java:595)
-57
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.IOException;
public class ProcessTest implements Runnable {
private final Process p;
public ProcessTest(final Process p) {
this.p = p;
}
public void run() {
System.out.println("Type="+ p.getClass().getName());
int exitValue = -57;
try {
try {
exitValue = p.waitFor();
}
catch(final InterruptedException IE) { //user cancel
//System.out.println("interrupted="+ Thread.interrupted());
System.out.println("interrupted="+ Thread.currentThread().isInterrupted());
p.destroy();
exitValue = p.waitFor();
}
}
catch(InterruptedException IE) { //should not happen
IE.printStackTrace(System.out);
}
finally {
System.out.println(exitValue);
}
}
public static void main(String[] args) {
if(args.length > 0) {
System.out.println(java.util.Arrays.toString(args));
try {
final Thread rt = startViaRt(args);
final Thread pb = startViaPb(args);
rt.start();
pb.start();
rt.interrupt(); //signal shutdown
pb.interrupt();
}
catch(IOException IOE) {
IOE.printStackTrace();
}
}
else {
System.out.println("Must supply an external process.");
}
}
private static Thread startViaRt(final String[] args) throws IOException {
final ProcessTest monitor = new ProcessTest(Runtime.getRuntime().exec(args));
final Thread t = new Thread(monitor);
return t;
}
private static Thread startViaPb(final String[] args) throws IOException {
final ProcessBuilder pb = new ProcessBuilder(args);
final ProcessTest monitor = new ProcessTest(pb.start());
final Thread t = new Thread(monitor);
return t;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Call Thread.interrupted() to clear the interrupt status in the catch block.