Почему я не могу выключить свой собственный ExecutorService в SecurityManager?

Под менеджером безопасности по умолчанию, если я создаю ExecutorService ( ThreadPoolExecutor в этом случае), я не могу выключить его, shutdown () просто вызывает checkPermission ("modifyThread") и, таким образом, немедленно умирает:

import java.util.concurrent.*;

class A {
    public static void main( String[] args) {
        Thread ct = Thread.currentThread();
        System.out.println("current thread: " + ct);
        ct.checkAccess(); // we have access to our own thread...
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(
            1, // one core thread
            1, // doesn't matter because queue is unbounded
            0, TimeUnit.SECONDS, // doesn't matter in this case
            new LinkedBlockingQueue(), /* unbound queue for
                                                  * our single thread */
            new ThreadFactory() {
                public Thread newThread(Runnable r) {
                    // obviously never gets called as we don't add any work
                    System.out.println("making thread");
                    return new Thread(r);
                }
            }
        );
        tpe.shutdown(); // raises security exception
    }
}

Sun JDK:

$ java -Djava.security.manager A текущая тема: тема [основная, 5, основная] Исключение в потоке "main" java.security.AccessControlException: доступ запрещен (java.lang.RuntimePermission modifyThread) в java.security.AccessControlContext.checkPermission (AccessControlContext.java:323) в java.security.AccessController.checkPermission (AccessController.java:546) в java.lang.SecurityManager.checkPermission (SecurityManager.java:532) в java.util.concurrent.ThreadPoolExecutor.shutdown (ThreadPoolExecutor.java:1094) в A.main (A.java:22)

OpenJDK:

$ java -Djava.security.manager A текущая тема: тема [основная, 5, основная] Исключение в потоке "main" java.security.AccessControlException: доступ запрещен (java.lang.RuntimePermission modifyThread) в java.security.AccessControlContext.checkPermission (AccessControlContext.java:342) в java.security.AccessController.checkPermission (AccessController.java:553) at java.lang.SecurityManager.checkPermission (SecurityManager.java:549) в java.util.concurrent.ThreadPoolExecutor.checkShutdownAccess (ThreadPoolExecutor.java:711) в java.util.concurrent.ThreadPoolExecutor.shutdown (ThreadPoolExecutor.java:1351) в A.main (A.java:22)

Почему ??????? Каковы последствия для безопасности создания пула потоков, который контролируется только вами , и его закрытия? Это ошибка в реализациях или я что-то упустил?

Давайте посмотрим, что говорит спецификация для ExecutorService.shutdown ...

Инициирует упорядоченное завершение работы, в котором выполняются ранее представленные задачи. , но никакие новые задачи не будут приняты. Вызов не имеет никакого дополнительного эффекта, если он уже выключен.

Броски: SecurityException - если менеджер безопасности существует, и закрытие этого ExecutorService может манипулировать потоками, которые вызывающему не разрешено изменять, потому что он не содержит RuntimePermission ("modifyThread"), или метод checkAccess менеджера безопасности запрещает доступ.

This .. примерно так же расплывчато, как может. В спецификации ничего не сказано о каких-либо «системных потоках», создаваемых в течение жизненного цикла ExecutorService, и, более того, позволяет вам предоставлять свои собственные потоки , что является доказательством того, что должно быть нет «системных потоков», задействованных при этом. (Как было сделано выше в моем примере источника)

Такое чувство, что разработчики Java SE увидели, что для shutdown возможно поднять SecurityException , поэтому они были похожи на " приватная статическая финальная RuntimePermission shutdownPerm = new RuntimePermission ("modifyThread");

... что, насколько я могу сказать, не имеет никакого смысла, поскольку modifyThread подразумевает доступ к системным потокам , а также здесь нет системных потоков, фактически нет вообще никаких потоков, потому что я не отправлял никаких работ или предварительных запусков, и даже если бы были потоки, они были бы моими потоками потому что я передал в ThreadFactory . В спецификации ничего не говорится о магическом умирании, кроме того, что если системные потоки задействованы (они не участвуют), может быть SecurityException .

По сути, почему я не могу просто удалить линия, которая проверяет доступ к системным потокам? Я не вижу никаких последствий для безопасности, призывающих к этому. И как еще никто не сталкивался с этим вопросом ??? Я' мы видели сообщение о системе отслеживания проблем, где они «решили» эту проблему, изменив вызов на shutdownNow на shutdown , очевидно, что это не исправило их.

16
задан Tom Hawtin - tackline 30 August 2010 в 01:55
поделиться