--- old/modules/graphics/src/main/java/javafx/concurrent/Task.java 2014-11-20 16:35:45.843621100 -0800 +++ new/modules/graphics/src/main/java/javafx/concurrent/Task.java 2014-11-20 16:35:45.116579500 -0800 @@ -25,6 +25,9 @@ package javafx.concurrent; +import java.security.AccessController; +import java.security.Permission; +import java.security.PrivilegedAction; import javafx.application.Platform; import javafx.beans.property.BooleanProperty; import javafx.beans.property.DoubleProperty; @@ -994,9 +997,20 @@ return cancel(true); } + // Need to assert the modifyThread permission so an app can cancel + // a task that it created (the default executor for the service runs in + // its own thread group) + // Note that this is needed when running as an applet or a web start app. + private static final Permission modifyThreadPerm = new RuntimePermission("modifyThread"); + @Override public boolean cancel(boolean mayInterruptIfRunning) { // Delegate to the super implementation to actually attempt to cancel this thing - boolean flag = super.cancel(mayInterruptIfRunning); + // Assert the modifyThread permission + boolean flag = AccessController.doPrivileged( + (PrivilegedAction) () -> super.cancel(mayInterruptIfRunning), + null, + modifyThreadPerm); + // If cancel succeeded (according to the semantics of the Future cancel method), // then we need to make sure the State flag is set appropriately if (flag) {