ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ExecutorsTest.java
Revision: 1.48
Committed: Sat Mar 18 20:42:20 2017 UTC (7 years, 1 month ago) by jsr166
Branch: MAIN
Changes since 1.47: +8 -16 lines
Log Message:
better assertion style

File Contents

# User Rev Content
1 dl 1.1 /*
2 dl 1.12 * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4 jsr166 1.37 * http://creativecommons.org/publicdomain/zero/1.0/
5 jsr166 1.20 * Other contributors include Andrew Wright, Jeffrey Hayes,
6     * Pat Fisher, Mike Judd.
7 dl 1.1 */
8    
9 jsr166 1.26 import static java.util.concurrent.TimeUnit.MILLISECONDS;
10 jsr166 1.43
11     import java.security.AccessControlContext;
12     import java.security.AccessControlException;
13     import java.security.AccessController;
14     import java.security.PrivilegedAction;
15     import java.security.PrivilegedExceptionAction;
16     import java.util.ArrayList;
17     import java.util.List;
18     import java.util.concurrent.Callable;
19     import java.util.concurrent.CountDownLatch;
20     import java.util.concurrent.Executors;
21     import java.util.concurrent.ExecutorService;
22     import java.util.concurrent.Future;
23     import java.util.concurrent.ScheduledExecutorService;
24     import java.util.concurrent.ThreadPoolExecutor;
25    
26     import junit.framework.Test;
27     import junit.framework.TestSuite;
28 dl 1.1
29 jsr166 1.22 public class ExecutorsTest extends JSR166TestCase {
30 dl 1.1 public static void main(String[] args) {
31 jsr166 1.45 main(suite(), args);
32 dl 1.1 }
33     public static Test suite() {
34 tim 1.9 return new TestSuite(ExecutorsTest.class);
35 dl 1.1 }
36    
37 dl 1.5 /**
38     * A newCachedThreadPool can execute runnables
39     */
40     public void testNewCachedThreadPool1() {
41 jsr166 1.46 final ExecutorService e = Executors.newCachedThreadPool();
42     try (PoolCleaner cleaner = cleaner(e)) {
43     e.execute(new NoOpRunnable());
44     e.execute(new NoOpRunnable());
45     e.execute(new NoOpRunnable());
46     }
47 dl 1.5 }
48    
49     /**
50     * A newCachedThreadPool with given ThreadFactory can execute runnables
51     */
52     public void testNewCachedThreadPool2() {
53 jsr166 1.46 final ExecutorService e = Executors.newCachedThreadPool(new SimpleThreadFactory());
54     try (PoolCleaner cleaner = cleaner(e)) {
55     e.execute(new NoOpRunnable());
56     e.execute(new NoOpRunnable());
57     e.execute(new NoOpRunnable());
58     }
59 dl 1.5 }
60    
61     /**
62     * A newCachedThreadPool with null ThreadFactory throws NPE
63     */
64     public void testNewCachedThreadPool3() {
65     try {
66     ExecutorService e = Executors.newCachedThreadPool(null);
67     shouldThrow();
68 jsr166 1.23 } catch (NullPointerException success) {}
69 dl 1.5 }
70    
71     /**
72     * A new SingleThreadExecutor can execute runnables
73     */
74     public void testNewSingleThreadExecutor1() {
75 jsr166 1.46 final ExecutorService e = Executors.newSingleThreadExecutor();
76     try (PoolCleaner cleaner = cleaner(e)) {
77     e.execute(new NoOpRunnable());
78     e.execute(new NoOpRunnable());
79     e.execute(new NoOpRunnable());
80     }
81 dl 1.5 }
82    
83     /**
84     * A new SingleThreadExecutor with given ThreadFactory can execute runnables
85     */
86     public void testNewSingleThreadExecutor2() {
87 jsr166 1.46 final ExecutorService e = Executors.newSingleThreadExecutor(new SimpleThreadFactory());
88     try (PoolCleaner cleaner = cleaner(e)) {
89     e.execute(new NoOpRunnable());
90     e.execute(new NoOpRunnable());
91     e.execute(new NoOpRunnable());
92     }
93 dl 1.5 }
94    
95     /**
96     * A new SingleThreadExecutor with null ThreadFactory throws NPE
97     */
98     public void testNewSingleThreadExecutor3() {
99     try {
100     ExecutorService e = Executors.newSingleThreadExecutor(null);
101     shouldThrow();
102 jsr166 1.23 } catch (NullPointerException success) {}
103 dl 1.5 }
104    
105     /**
106 dl 1.11 * A new SingleThreadExecutor cannot be casted to concrete implementation
107     */
108     public void testCastNewSingleThreadExecutor() {
109 jsr166 1.46 final ExecutorService e = Executors.newSingleThreadExecutor();
110     try (PoolCleaner cleaner = cleaner(e)) {
111     try {
112     ThreadPoolExecutor tpe = (ThreadPoolExecutor)e;
113     shouldThrow();
114     } catch (ClassCastException success) {}
115 dl 1.11 }
116     }
117    
118     /**
119 dl 1.5 * A new newFixedThreadPool can execute runnables
120     */
121     public void testNewFixedThreadPool1() {
122 jsr166 1.46 final ExecutorService e = Executors.newFixedThreadPool(2);
123     try (PoolCleaner cleaner = cleaner(e)) {
124     e.execute(new NoOpRunnable());
125     e.execute(new NoOpRunnable());
126     e.execute(new NoOpRunnable());
127     }
128 dl 1.5 }
129    
130     /**
131     * A new newFixedThreadPool with given ThreadFactory can execute runnables
132     */
133     public void testNewFixedThreadPool2() {
134 jsr166 1.46 final ExecutorService e = Executors.newFixedThreadPool(2, new SimpleThreadFactory());
135     try (PoolCleaner cleaner = cleaner(e)) {
136     e.execute(new NoOpRunnable());
137     e.execute(new NoOpRunnable());
138     e.execute(new NoOpRunnable());
139     }
140 dl 1.5 }
141    
142     /**
143     * A new newFixedThreadPool with null ThreadFactory throws NPE
144     */
145     public void testNewFixedThreadPool3() {
146     try {
147     ExecutorService e = Executors.newFixedThreadPool(2, null);
148     shouldThrow();
149 jsr166 1.23 } catch (NullPointerException success) {}
150 dl 1.5 }
151    
152     /**
153     * A new newFixedThreadPool with 0 threads throws IAE
154     */
155     public void testNewFixedThreadPool4() {
156     try {
157     ExecutorService e = Executors.newFixedThreadPool(0);
158     shouldThrow();
159 jsr166 1.23 } catch (IllegalArgumentException success) {}
160 dl 1.5 }
161 dl 1.1
162 dl 1.2 /**
163 dl 1.11 * An unconfigurable newFixedThreadPool can execute runnables
164     */
165 jsr166 1.42 public void testUnconfigurableExecutorService() {
166 jsr166 1.46 final ExecutorService e = Executors.unconfigurableExecutorService(Executors.newFixedThreadPool(2));
167     try (PoolCleaner cleaner = cleaner(e)) {
168     e.execute(new NoOpRunnable());
169     e.execute(new NoOpRunnable());
170     e.execute(new NoOpRunnable());
171     }
172 dl 1.11 }
173    
174     /**
175     * unconfigurableExecutorService(null) throws NPE
176     */
177 jsr166 1.42 public void testUnconfigurableExecutorServiceNPE() {
178 dl 1.11 try {
179     ExecutorService e = Executors.unconfigurableExecutorService(null);
180 jsr166 1.23 shouldThrow();
181     } catch (NullPointerException success) {}
182 dl 1.11 }
183    
184     /**
185     * unconfigurableScheduledExecutorService(null) throws NPE
186     */
187 jsr166 1.42 public void testUnconfigurableScheduledExecutorServiceNPE() {
188 dl 1.11 try {
189     ExecutorService e = Executors.unconfigurableScheduledExecutorService(null);
190 jsr166 1.23 shouldThrow();
191     } catch (NullPointerException success) {}
192 dl 1.11 }
193    
194     /**
195     * a newSingleThreadScheduledExecutor successfully runs delayed task
196     */
197 jsr166 1.23 public void testNewSingleThreadScheduledExecutor() throws Exception {
198 jsr166 1.46 final ScheduledExecutorService p = Executors.newSingleThreadScheduledExecutor();
199     try (PoolCleaner cleaner = cleaner(p)) {
200 jsr166 1.42 final CountDownLatch proceed = new CountDownLatch(1);
201 jsr166 1.35 final Runnable task = new CheckedRunnable() {
202     public void realRun() {
203 jsr166 1.42 await(proceed);
204 jsr166 1.35 }};
205 jsr166 1.42 long startTime = System.nanoTime();
206 jsr166 1.35 Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
207 jsr166 1.42 timeoutMillis(), MILLISECONDS);
208 jsr166 1.35 assertFalse(f.isDone());
209 jsr166 1.42 proceed.countDown();
210     assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
211 jsr166 1.36 assertSame(Boolean.TRUE, f.get());
212 jsr166 1.35 assertTrue(f.isDone());
213 jsr166 1.42 assertFalse(f.isCancelled());
214     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
215 jsr166 1.35 }
216 dl 1.11 }
217    
218     /**
219     * a newScheduledThreadPool successfully runs delayed task
220     */
221 jsr166 1.42 public void testNewScheduledThreadPool() throws Exception {
222 jsr166 1.46 final ScheduledExecutorService p = Executors.newScheduledThreadPool(2);
223     try (PoolCleaner cleaner = cleaner(p)) {
224 jsr166 1.42 final CountDownLatch proceed = new CountDownLatch(1);
225 jsr166 1.35 final Runnable task = new CheckedRunnable() {
226     public void realRun() {
227 jsr166 1.42 await(proceed);
228 jsr166 1.35 }};
229 jsr166 1.42 long startTime = System.nanoTime();
230 jsr166 1.35 Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
231 jsr166 1.42 timeoutMillis(), MILLISECONDS);
232 jsr166 1.35 assertFalse(f.isDone());
233 jsr166 1.42 proceed.countDown();
234     assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
235 jsr166 1.36 assertSame(Boolean.TRUE, f.get());
236 jsr166 1.35 assertTrue(f.isDone());
237 jsr166 1.42 assertFalse(f.isCancelled());
238     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
239 jsr166 1.35 }
240 dl 1.11 }
241    
242     /**
243 jsr166 1.24 * an unconfigurable newScheduledThreadPool successfully runs delayed task
244 dl 1.11 */
245 jsr166 1.42 public void testUnconfigurableScheduledExecutorService() throws Exception {
246 jsr166 1.46 final ScheduledExecutorService p =
247 jsr166 1.35 Executors.unconfigurableScheduledExecutorService
248     (Executors.newScheduledThreadPool(2));
249 jsr166 1.46 try (PoolCleaner cleaner = cleaner(p)) {
250 jsr166 1.42 final CountDownLatch proceed = new CountDownLatch(1);
251 jsr166 1.35 final Runnable task = new CheckedRunnable() {
252     public void realRun() {
253 jsr166 1.42 await(proceed);
254 jsr166 1.35 }};
255 jsr166 1.42 long startTime = System.nanoTime();
256 jsr166 1.35 Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
257 jsr166 1.42 timeoutMillis(), MILLISECONDS);
258 jsr166 1.35 assertFalse(f.isDone());
259 jsr166 1.42 proceed.countDown();
260     assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
261 jsr166 1.36 assertSame(Boolean.TRUE, f.get());
262 jsr166 1.35 assertTrue(f.isDone());
263 jsr166 1.42 assertFalse(f.isCancelled());
264     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
265 jsr166 1.35 }
266 dl 1.11 }
267    
268     /**
269 jsr166 1.34 * Future.get on submitted tasks will time out if they compute too long.
270 dl 1.2 */
271 jsr166 1.23 public void testTimedCallable() throws Exception {
272 jsr166 1.40 final ExecutorService[] executors = {
273     Executors.newSingleThreadExecutor(),
274     Executors.newCachedThreadPool(),
275     Executors.newFixedThreadPool(2),
276     Executors.newScheduledThreadPool(2),
277     };
278    
279 jsr166 1.33 final Runnable sleeper = new CheckedInterruptedRunnable() {
280     public void realRun() throws InterruptedException {
281 dl 1.39 delay(LONG_DELAY_MS);
282 jsr166 1.33 }};
283 jsr166 1.40
284 jsr166 1.47 List<Thread> threads = new ArrayList<>();
285 jsr166 1.40 for (final ExecutorService executor : executors) {
286     threads.add(newStartedThread(new CheckedRunnable() {
287     public void realRun() {
288     Future future = executor.submit(sleeper);
289     assertFutureTimesOut(future);
290     }}));
291 dl 1.2 }
292 jsr166 1.40 for (Thread thread : threads)
293     awaitTermination(thread);
294     for (ExecutorService executor : executors)
295     joinPool(executor);
296 dl 1.2 }
297    
298 dl 1.8 /**
299     * ThreadPoolExecutor using defaultThreadFactory has
300     * specified group, priority, daemon status, and name
301     */
302 jsr166 1.23 public void testDefaultThreadFactory() throws Exception {
303 tim 1.9 final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
304 jsr166 1.42 final CountDownLatch done = new CountDownLatch(1);
305 jsr166 1.31 Runnable r = new CheckedRunnable() {
306     public void realRun() {
307     try {
308     Thread current = Thread.currentThread();
309 jsr166 1.48 assertFalse(current.isDaemon());
310 jsr166 1.31 assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
311     SecurityManager s = System.getSecurityManager();
312 jsr166 1.48 assertSame(current.getThreadGroup(),
313     (s == null) ? egroup : s.getThreadGroup());
314     assertTrue(current.getName().endsWith("thread-1"));
315 jsr166 1.31 } catch (SecurityException ok) {
316     // Also pass if not allowed to change setting
317 tim 1.9 }
318 jsr166 1.42 done.countDown();
319 jsr166 1.31 }};
320 tim 1.9 ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
321 jsr166 1.46 try (PoolCleaner cleaner = cleaner(e)) {
322     e.execute(r);
323     await(done);
324 dl 1.14 }
325 dl 1.8 }
326    
327     /**
328     * ThreadPoolExecutor using privilegedThreadFactory has
329     * specified group, priority, daemon status, name,
330     * access control context and context class loader
331     */
332 jsr166 1.23 public void testPrivilegedThreadFactory() throws Exception {
333 jsr166 1.42 final CountDownLatch done = new CountDownLatch(1);
334 jsr166 1.29 Runnable r = new CheckedRunnable() {
335     public void realRun() throws Exception {
336     final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
337     final ClassLoader thisccl = Thread.currentThread().getContextClassLoader();
338     final AccessControlContext thisacc = AccessController.getContext();
339     Runnable r = new CheckedRunnable() {
340     public void realRun() {
341 jsr166 1.25 Thread current = Thread.currentThread();
342 jsr166 1.48 assertFalse(current.isDaemon());
343 jsr166 1.29 assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
344 jsr166 1.25 SecurityManager s = System.getSecurityManager();
345 jsr166 1.48 assertSame(current.getThreadGroup(),
346     (s == null) ? egroup : s.getThreadGroup());
347     assertTrue(current.getName().endsWith("thread-1"));
348 jsr166 1.31 assertSame(thisccl, current.getContextClassLoader());
349     assertEquals(thisacc, AccessController.getContext());
350 jsr166 1.42 done.countDown();
351 jsr166 1.29 }};
352     ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory());
353 jsr166 1.46 try (PoolCleaner cleaner = cleaner(e)) {
354     e.execute(r);
355     await(done);
356     }
357 jsr166 1.29 }};
358    
359     runWithPermissions(r,
360     new RuntimePermission("getClassLoader"),
361     new RuntimePermission("setContextClassLoader"),
362     new RuntimePermission("modifyThread"));
363     }
364 jsr166 1.20
365 jsr166 1.29 boolean haveCCLPermissions() {
366     SecurityManager sm = System.getSecurityManager();
367     if (sm != null) {
368     try {
369     sm.checkPermission(new RuntimePermission("setContextClassLoader"));
370     sm.checkPermission(new RuntimePermission("getClassLoader"));
371     } catch (AccessControlException e) {
372     return false;
373     }
374 tim 1.9 }
375 jsr166 1.29 return true;
376 dl 1.8 }
377 dl 1.11
378 dl 1.16 void checkCCL() {
379 dl 1.18 SecurityManager sm = System.getSecurityManager();
380     if (sm != null) {
381     sm.checkPermission(new RuntimePermission("setContextClassLoader"));
382 jsr166 1.19 sm.checkPermission(new RuntimePermission("getClassLoader"));
383 dl 1.18 }
384 dl 1.16 }
385    
386     class CheckCCL implements Callable<Object> {
387 dl 1.11 public Object call() {
388 dl 1.16 checkCCL();
389 dl 1.11 return null;
390     }
391     }
392    
393     /**
394     * Without class loader permissions, creating
395     * privilegedCallableUsingCurrentClassLoader throws ACE
396     */
397     public void testCreatePrivilegedCallableUsingCCLWithNoPrivs() {
398 jsr166 1.29 Runnable r = new CheckedRunnable() {
399     public void realRun() throws Exception {
400     if (System.getSecurityManager() == null)
401     return;
402     try {
403     Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
404     shouldThrow();
405     } catch (AccessControlException success) {}
406     }};
407 dl 1.16
408 jsr166 1.29 runWithoutPermissions(r);
409 dl 1.11 }
410    
411     /**
412 dl 1.16 * With class loader permissions, calling
413     * privilegedCallableUsingCurrentClassLoader does not throw ACE
414 dl 1.11 */
415 jsr166 1.42 public void testPrivilegedCallableUsingCCLWithPrivs() throws Exception {
416 jsr166 1.29 Runnable r = new CheckedRunnable() {
417     public void realRun() throws Exception {
418     Executors.privilegedCallableUsingCurrentClassLoader
419     (new NoOpCallable())
420     .call();
421     }};
422    
423     runWithPermissions(r,
424     new RuntimePermission("getClassLoader"),
425     new RuntimePermission("setContextClassLoader"));
426 dl 1.11 }
427    
428     /**
429     * Without permissions, calling privilegedCallable throws ACE
430     */
431 jsr166 1.42 public void testPrivilegedCallableWithNoPrivs() throws Exception {
432 jsr166 1.32 // Avoid classloader-related SecurityExceptions in swingui.TestRunner
433     Executors.privilegedCallable(new CheckCCL());
434    
435 jsr166 1.29 Runnable r = new CheckedRunnable() {
436     public void realRun() throws Exception {
437     if (System.getSecurityManager() == null)
438     return;
439     Callable task = Executors.privilegedCallable(new CheckCCL());
440     try {
441     task.call();
442     shouldThrow();
443     } catch (AccessControlException success) {}
444     }};
445    
446     runWithoutPermissions(r);
447    
448     // It seems rather difficult to test that the
449     // AccessControlContext of the privilegedCallable is used
450     // instead of its caller. Below is a failed attempt to do
451     // that, which does not work because the AccessController
452     // cannot capture the internal state of the current Policy.
453     // It would be much more work to differentiate based on,
454     // e.g. CodeSource.
455    
456     // final AccessControlContext[] noprivAcc = new AccessControlContext[1];
457     // final Callable[] task = new Callable[1];
458    
459     // runWithPermissions
460     // (new CheckedRunnable() {
461     // public void realRun() {
462     // if (System.getSecurityManager() == null)
463     // return;
464     // noprivAcc[0] = AccessController.getContext();
465     // task[0] = Executors.privilegedCallable(new CheckCCL());
466     // try {
467     // AccessController.doPrivileged(new PrivilegedAction<Void>() {
468     // public Void run() {
469     // checkCCL();
470     // return null;
471     // }}, noprivAcc[0]);
472     // shouldThrow();
473     // } catch (AccessControlException success) {}
474     // }});
475    
476     // runWithPermissions
477     // (new CheckedRunnable() {
478     // public void realRun() throws Exception {
479     // if (System.getSecurityManager() == null)
480     // return;
481     // // Verify that we have an underprivileged ACC
482     // try {
483     // AccessController.doPrivileged(new PrivilegedAction<Void>() {
484     // public Void run() {
485     // checkCCL();
486     // return null;
487     // }}, noprivAcc[0]);
488     // shouldThrow();
489     // } catch (AccessControlException success) {}
490    
491     // try {
492     // task[0].call();
493     // shouldThrow();
494     // } catch (AccessControlException success) {}
495     // }},
496     // new RuntimePermission("getClassLoader"),
497     // new RuntimePermission("setContextClassLoader"));
498 dl 1.11 }
499    
500     /**
501     * With permissions, calling privilegedCallable succeeds
502     */
503 jsr166 1.42 public void testPrivilegedCallableWithPrivs() throws Exception {
504 jsr166 1.29 Runnable r = new CheckedRunnable() {
505     public void realRun() throws Exception {
506     Executors.privilegedCallable(new CheckCCL()).call();
507     }};
508    
509 jsr166 1.38 runWithPermissions(r,
510 jsr166 1.29 new RuntimePermission("getClassLoader"),
511     new RuntimePermission("setContextClassLoader"));
512 dl 1.11 }
513    
514     /**
515     * callable(Runnable) returns null when called
516 jsr166 1.20 */
517 jsr166 1.23 public void testCallable1() throws Exception {
518     Callable c = Executors.callable(new NoOpRunnable());
519     assertNull(c.call());
520 dl 1.11 }
521    
522     /**
523     * callable(Runnable, result) returns result when called
524 jsr166 1.20 */
525 jsr166 1.23 public void testCallable2() throws Exception {
526     Callable c = Executors.callable(new NoOpRunnable(), one);
527 jsr166 1.27 assertSame(one, c.call());
528 dl 1.11 }
529    
530     /**
531     * callable(PrivilegedAction) returns its result when called
532 jsr166 1.20 */
533 jsr166 1.23 public void testCallable3() throws Exception {
534     Callable c = Executors.callable(new PrivilegedAction() {
535     public Object run() { return one; }});
536 jsr166 1.27 assertSame(one, c.call());
537 dl 1.11 }
538    
539     /**
540     * callable(PrivilegedExceptionAction) returns its result when called
541 jsr166 1.20 */
542 jsr166 1.23 public void testCallable4() throws Exception {
543     Callable c = Executors.callable(new PrivilegedExceptionAction() {
544     public Object run() { return one; }});
545 jsr166 1.27 assertSame(one, c.call());
546 dl 1.11 }
547    
548     /**
549     * callable(null Runnable) throws NPE
550 jsr166 1.20 */
551 dl 1.11 public void testCallableNPE1() {
552     try {
553 jsr166 1.23 Callable c = Executors.callable((Runnable) null);
554     shouldThrow();
555     } catch (NullPointerException success) {}
556 dl 1.11 }
557    
558     /**
559     * callable(null, result) throws NPE
560 jsr166 1.20 */
561 dl 1.11 public void testCallableNPE2() {
562     try {
563 jsr166 1.23 Callable c = Executors.callable((Runnable) null, one);
564     shouldThrow();
565     } catch (NullPointerException success) {}
566 dl 1.11 }
567    
568     /**
569     * callable(null PrivilegedAction) throws NPE
570 jsr166 1.20 */
571 dl 1.11 public void testCallableNPE3() {
572     try {
573 jsr166 1.23 Callable c = Executors.callable((PrivilegedAction) null);
574     shouldThrow();
575     } catch (NullPointerException success) {}
576 dl 1.11 }
577    
578     /**
579     * callable(null PrivilegedExceptionAction) throws NPE
580 jsr166 1.20 */
581 dl 1.11 public void testCallableNPE4() {
582     try {
583 jsr166 1.23 Callable c = Executors.callable((PrivilegedExceptionAction) null);
584     shouldThrow();
585     } catch (NullPointerException success) {}
586 dl 1.11 }
587    
588 dl 1.1 }