12 |
|
import java.security.PrivilegedAction; |
13 |
|
|
14 |
|
/** |
15 |
< |
* A {@link FutureTask} that executes with the given (or current, if |
16 |
< |
* not specified) access control context and/or the given (or current) |
17 |
< |
* context class loader. |
15 |
> |
* A {@link FutureTask} that executes, if allowed, with the current |
16 |
> |
* access control context and context class loader of the thread |
17 |
> |
* creating the task. A new <tt>PrivilegedFutureTask</tt> |
18 |
> |
* can be created within an {@link AccessController#doPrivileged} |
19 |
> |
* action to run tasks under the selected permission settings |
20 |
> |
* holding within that action. |
21 |
> |
* @see Executors |
22 |
|
* |
23 |
|
* @since 1.5 |
24 |
|
* @author Doug Lea |
25 |
|
*/ |
26 |
|
public class PrivilegedFutureTask<T> extends FutureTask<T> { |
27 |
+ |
private final ClassLoader ccl; |
28 |
+ |
private final AccessControlContext acc; |
29 |
|
|
30 |
|
/** |
31 |
|
* Constructs a <tt>PrivilegedFutureTask</tt> that will, upon running, |
40 |
|
super(task); |
41 |
|
this.ccl = Thread.currentThread().getContextClassLoader(); |
42 |
|
this.acc = AccessController.getContext(); |
37 |
– |
|
43 |
|
acc.checkPermission(new RuntimePermission("getContextClassLoader")); |
44 |
|
acc.checkPermission(new RuntimePermission("setContextClassLoader")); |
45 |
|
} |
46 |
|
|
47 |
< |
|
47 |
> |
/** |
48 |
> |
* Executes within the established access control and context |
49 |
> |
* class loader if possible, else causes invocations of {@link |
50 |
> |
* Future#get} to receive the associated AccessControlException. |
51 |
> |
*/ |
52 |
|
public void run() { |
53 |
< |
AccessController.doPrivileged(new PrivilegedAction() { |
54 |
< |
public Object run() { |
55 |
< |
runPrivileged(); |
56 |
< |
return null; |
57 |
< |
} |
49 |
< |
}, acc); |
53 |
> |
try { |
54 |
> |
AccessController.doPrivileged(new PrivilegedFutureAction(), acc); |
55 |
> |
} catch(Throwable ex) { |
56 |
> |
setException(ex); |
57 |
> |
} |
58 |
|
} |
59 |
|
|
60 |
< |
|
61 |
< |
private void runPrivileged() { |
62 |
< |
ClassLoader saved = null; |
63 |
< |
try { |
64 |
< |
ClassLoader current = Thread.currentThread().getContextClassLoader(); |
65 |
< |
if (ccl != current) { |
66 |
< |
Thread.currentThread().setContextClassLoader(ccl); |
67 |
< |
saved = current; |
68 |
< |
} |
69 |
< |
super.run(); |
70 |
< |
} |
71 |
< |
finally { |
72 |
< |
if (saved != null) |
73 |
< |
Thread.currentThread().setContextClassLoader(saved); |
74 |
< |
} |
60 |
> |
private class PrivilegedFutureAction implements PrivilegedAction { |
61 |
> |
public Object run() { |
62 |
> |
ClassLoader saved = null; |
63 |
> |
try { |
64 |
> |
ClassLoader current = Thread.currentThread().getContextClassLoader(); |
65 |
> |
if (ccl != current) { |
66 |
> |
Thread.currentThread().setContextClassLoader(ccl); |
67 |
> |
saved = current; |
68 |
> |
} |
69 |
> |
PrivilegedFutureTask.super.run(); |
70 |
> |
return null; |
71 |
> |
} finally { |
72 |
> |
if (saved != null) |
73 |
> |
Thread.currentThread().setContextClassLoader(saved); |
74 |
> |
} |
75 |
> |
} |
76 |
|
} |
68 |
– |
|
69 |
– |
private final ClassLoader ccl; |
70 |
– |
private final AccessControlContext acc; |
77 |
|
} |
72 |
– |
|