Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6531234
Votes 0
Synopsis What if FutureTask.cancel throws?
Category java:classes_util_concurrent
Reported Against
Release Fixed
State 5-Cause Known, bug
Priority: 3-Medium
Related Bugs
Submit Date 06-MAR-2007
Description
Jason writes:

What if cancel throws an exception?  The 
documentation does not list the possible SecurityException or the possible 
RuntimeException/Error from done().  Should a subsequent cancel be allowed 
to interrupt the runner if the first attempt was by a thread with out thread 
modify permission?

Jason


//Test case for Future fun.
import java.util.concurrent.*;
import java.util.*;
public class Cancel implements Callable<Void> {
    private final long sleep_ms;

    public static void main(String[] args) {
        cancelBeforeRun();
        cancelAfterRun();
        cancelCancelRun();
        lateArrivingGet(false);
        lateArrivingGet(true);
        securityCancel(false);
        securityCancel(true);
        evilDone();
        exit();
    }

    private static void cancelAfterRun() {
        System.err.println("cancelAfterRun");
        FutureTask task = new FutureTask(new Cancel(0L));
        task.run();
        testGoldenRule(task, false);
    }

    private static void cancelBeforeRun() {
        System.err.println("cancelBeforeRun");
        FutureTask task = new FutureTask(new Cancel(0L));
        testGoldenRule(task, false);
    }

    private static void cancelCancelRun() {
        System.err.println("cancelCancelRun");
        FutureTask task = new FutureTask(new Cancel(0L));
        task.cancel(false);
        testGoldenRule(task, false);
    }

    private static void lateArrivingGet(boolean mi) {
        System.err.println("lateArrivingGet("+ mi +')');
        FutureTask task = new FutureTask(new Cancel(15 * 1000L)) {
            public void run() {
                super.run();
                exit();
            }
        };
        new Thread(task).start();
        try {
            Thread.sleep(1000L);
        }
        catch(InterruptedException IE) {
            throw new AssertionError(IE);
        }
        testGoldenRule(task, mi);
    }

    private static void evilDone() {
        System.err.println("evilDone");
        FutureTask task = new FutureTask(new Cancel(15 * 1000L)) {
            protected void done() {
                if(super.isCancelled()) {
                    throw new InternalError();
                }
            }
        };
        testGoldenRule(task, false);
    }

    public static void securityCancel(boolean mi) {
            FutureTask task = new FutureTask(new Cancel(15 * 1000L)) {
                public void run() {
                    super.run();
                    exit();
                }
            };

            new Thread(task).start();
            try {
                Thread.sleep(1000L);
            }
            catch(InterruptedException IE) {
                throw new AssertionError(IE);
            }

       try {
            System.setSecurityManager(new SecurityManager() {
             public void checkAccess(Thread t) {
                 throw new SecurityException(t.toString());
             }
            });
            testGoldenRule(task, mi);
        }
        finally {
            System.setSecurityManager(null);
        }
    }


    private static void testGoldenRule(Future task, boolean mi) {
        try {
            if(!task.cancel(mi)) {
                try {
                    try {
                        task.get(0L, TimeUnit.NANOSECONDS);
                        throw new AssertionError("Get returned.");
                    }
                    catch(TimeoutException TE) {
                       if(task.isCancelled() && !task.isDone()) {
                            new AssertionError("Cancelled but not done.")
                            .initCause(TE).printStackTrace();
                       }
                       else {
                           task.get();
                           throw new AssertionError("Get returned.");
                       }
                    }
                }
                catch(InterruptedException IE) {
                    throw new AssertionError(IE);
                }
                catch(ExecutionException EE) {
                    EE.printStackTrace();
                }
                catch(CancellationException CE) {
                    new 
AssertionError(CE.toString()).initCause(CE).printStackTrace();
                }
            }
            else {
                System.err.println("Pass (cancel was true).");
            }
        }
        catch(SecurityException SE) {
            SE.printStackTrace();
            try {
                testGoldenRule(task, mi);
            }
            catch(SecurityException again) {
                System.err.println("Pass (failed twice).");
            }
        }
        catch(InternalError IE) {
            IE.printStackTrace();
            testGoldenRule(task, mi);
        }
    }

    private static void exit() {
        System.err.println(new Date(System.currentTimeMillis()) +", "+
                Thread.currentThread());

    }

    public Cancel(final long sleep_ms) {
        this.sleep_ms = sleep_ms;
    }

    public Void call() throws Exception {
        Thread.sleep(sleep_ms);
        throw new Exception("Pass");
    }
}
Posted Date : 2007-03-06 02:21:39.0
Work Around
N/A
Evaluation
Submitter is correct; doc needs work.
Posted Date : 2007-03-06 02:22:08.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang