11 |
|
import java.security.AccessController; |
12 |
|
import java.security.PrivilegedAction; |
13 |
|
import java.security.PrivilegedExceptionAction; |
14 |
+ |
import java.security.PrivilegedActionException; |
15 |
|
import java.security.AccessControlException; |
16 |
+ |
import sun.security.util.SecurityConstants; |
17 |
|
|
18 |
|
/** |
19 |
|
* Factory and utility methods for {@link Executor}, {@link |
434 |
|
static final class RunnableAdapter<T> implements Callable<T> { |
435 |
|
final Runnable task; |
436 |
|
final T result; |
437 |
< |
RunnableAdapter(Runnable task, T result) { |
437 |
> |
RunnableAdapter(Runnable task, T result) { |
438 |
|
this.task = task; |
439 |
|
this.result = result; |
440 |
|
} |
448 |
|
* A callable that runs under established access control settings |
449 |
|
*/ |
450 |
|
static final class PrivilegedCallable<T> implements Callable<T> { |
449 |
– |
private final AccessControlContext acc; |
451 |
|
private final Callable<T> task; |
452 |
< |
private T result; |
453 |
< |
private Exception exception; |
454 |
< |
PrivilegedCallable(Callable<T> task) { |
452 |
> |
private final AccessControlContext acc; |
453 |
> |
|
454 |
> |
PrivilegedCallable(Callable<T> task) { |
455 |
|
this.task = task; |
456 |
|
this.acc = AccessController.getContext(); |
457 |
|
} |
458 |
|
|
459 |
|
public T call() throws Exception { |
460 |
< |
AccessController.doPrivileged(new PrivilegedAction<T>() { |
461 |
< |
public T run() { |
462 |
< |
try { |
463 |
< |
result = task.call(); |
464 |
< |
} catch (Exception ex) { |
465 |
< |
exception = ex; |
466 |
< |
} |
467 |
< |
return null; |
468 |
< |
} |
469 |
< |
}, acc); |
469 |
< |
if (exception != null) |
470 |
< |
throw exception; |
471 |
< |
else |
472 |
< |
return result; |
460 |
> |
try { |
461 |
> |
return AccessController.doPrivileged( |
462 |
> |
new PrivilegedExceptionAction<T>() { |
463 |
> |
public T run() throws Exception { |
464 |
> |
return task.call(); |
465 |
> |
} |
466 |
> |
}, acc); |
467 |
> |
} catch (PrivilegedActionException e) { |
468 |
> |
throw e.getException(); |
469 |
> |
} |
470 |
|
} |
471 |
|
} |
472 |
|
|
475 |
|
* current ClassLoader |
476 |
|
*/ |
477 |
|
static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> { |
481 |
– |
private final ClassLoader ccl; |
482 |
– |
private final AccessControlContext acc; |
478 |
|
private final Callable<T> task; |
479 |
< |
private T result; |
480 |
< |
private Exception exception; |
481 |
< |
PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) { |
479 |
> |
private final AccessControlContext acc; |
480 |
> |
private final ClassLoader ccl; |
481 |
> |
|
482 |
> |
PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) { |
483 |
> |
SecurityManager sm = System.getSecurityManager(); |
484 |
> |
if (sm != null) { |
485 |
> |
// Calls to getContextClassLoader from this class |
486 |
> |
// never trigger a security check, but we check |
487 |
> |
// whether our callers have this permission anyways. |
488 |
> |
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); |
489 |
> |
|
490 |
> |
// Whether setContextClassLoader turns out to be necessary |
491 |
> |
// or not, we fail fast if permission is not available. |
492 |
> |
sm.checkPermission(new RuntimePermission("setContextClassLoader")); |
493 |
> |
} |
494 |
|
this.task = task; |
488 |
– |
this.ccl = Thread.currentThread().getContextClassLoader(); |
495 |
|
this.acc = AccessController.getContext(); |
496 |
< |
acc.checkPermission(new RuntimePermission("getContextClassLoader")); |
491 |
< |
acc.checkPermission(new RuntimePermission("setContextClassLoader")); |
496 |
> |
this.ccl = Thread.currentThread().getContextClassLoader(); |
497 |
|
} |
498 |
|
|
499 |
|
public T call() throws Exception { |
500 |
< |
AccessController.doPrivileged(new PrivilegedAction<T>() { |
501 |
< |
public T run() { |
502 |
< |
ClassLoader savedcl = null; |
503 |
< |
Thread t = Thread.currentThread(); |
504 |
< |
try { |
505 |
< |
ClassLoader cl = t.getContextClassLoader(); |
506 |
< |
if (ccl != cl) { |
507 |
< |
t.setContextClassLoader(ccl); |
508 |
< |
savedcl = cl; |
509 |
< |
} |
510 |
< |
result = task.call(); |
511 |
< |
} catch (Exception ex) { |
512 |
< |
exception = ex; |
513 |
< |
} finally { |
514 |
< |
if (savedcl != null) |
515 |
< |
t.setContextClassLoader(savedcl); |
516 |
< |
} |
517 |
< |
return null; |
518 |
< |
} |
519 |
< |
}, acc); |
520 |
< |
if (exception != null) |
521 |
< |
throw exception; |
517 |
< |
else |
518 |
< |
return result; |
500 |
> |
try { |
501 |
> |
return AccessController.doPrivileged( |
502 |
> |
new PrivilegedExceptionAction<T>() { |
503 |
> |
public T run() throws Exception { |
504 |
> |
ClassLoader savedcl = null; |
505 |
> |
Thread t = Thread.currentThread(); |
506 |
> |
try { |
507 |
> |
ClassLoader cl = t.getContextClassLoader(); |
508 |
> |
if (ccl != cl) { |
509 |
> |
t.setContextClassLoader(ccl); |
510 |
> |
savedcl = cl; |
511 |
> |
} |
512 |
> |
return task.call(); |
513 |
> |
} finally { |
514 |
> |
if (savedcl != null) |
515 |
> |
t.setContextClassLoader(savedcl); |
516 |
> |
} |
517 |
> |
} |
518 |
> |
}, acc); |
519 |
> |
} catch (PrivilegedActionException e) { |
520 |
> |
throw e.getException(); |
521 |
> |
} |
522 |
|
} |
523 |
|
} |
524 |
|
|
526 |
|
* The default thread factory |
527 |
|
*/ |
528 |
|
static class DefaultThreadFactory implements ThreadFactory { |
529 |
< |
static final AtomicInteger poolNumber = new AtomicInteger(1); |
530 |
< |
final ThreadGroup group; |
531 |
< |
final AtomicInteger threadNumber = new AtomicInteger(1); |
532 |
< |
final String namePrefix; |
529 |
> |
private static final AtomicInteger poolNumber = new AtomicInteger(1); |
530 |
> |
private final ThreadGroup group; |
531 |
> |
private final AtomicInteger threadNumber = new AtomicInteger(1); |
532 |
> |
private final String namePrefix; |
533 |
|
|
534 |
|
DefaultThreadFactory() { |
535 |
|
SecurityManager s = System.getSecurityManager(); |
553 |
|
} |
554 |
|
|
555 |
|
/** |
556 |
< |
* Thread factory capturing access control and class loader |
556 |
> |
* Thread factory capturing access control context and class loader |
557 |
|
*/ |
558 |
|
static class PrivilegedThreadFactory extends DefaultThreadFactory { |
556 |
– |
private final ClassLoader ccl; |
559 |
|
private final AccessControlContext acc; |
560 |
+ |
private final ClassLoader ccl; |
561 |
|
|
562 |
|
PrivilegedThreadFactory() { |
563 |
|
super(); |
564 |
< |
this.ccl = Thread.currentThread().getContextClassLoader(); |
564 |
> |
SecurityManager sm = System.getSecurityManager(); |
565 |
> |
if (sm != null) { |
566 |
> |
// Calls to getContextClassLoader from this class |
567 |
> |
// never trigger a security check, but we check |
568 |
> |
// whether our callers have this permission anyways. |
569 |
> |
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); |
570 |
> |
|
571 |
> |
// Fail fast |
572 |
> |
sm.checkPermission(new RuntimePermission("setContextClassLoader")); |
573 |
> |
} |
574 |
|
this.acc = AccessController.getContext(); |
575 |
< |
acc.checkPermission(new RuntimePermission("setContextClassLoader")); |
575 |
> |
this.ccl = Thread.currentThread().getContextClassLoader(); |
576 |
|
} |
577 |
|
|
578 |
|
public Thread newThread(final Runnable r) { |
579 |
|
return super.newThread(new Runnable() { |
580 |
|
public void run() { |
581 |
< |
AccessController.doPrivileged(new PrivilegedAction<Object>() { |
582 |
< |
public Object run() { |
581 |
> |
AccessController.doPrivileged(new PrivilegedAction<Void>() { |
582 |
> |
public Void run() { |
583 |
|
Thread.currentThread().setContextClassLoader(ccl); |
584 |
|
r.run(); |
585 |
|
return null; |
588 |
|
} |
589 |
|
}); |
590 |
|
} |
579 |
– |
|
591 |
|
} |
592 |
|
|
593 |
|
/** |