Constructor.newInstance против Class.newInstance с помощью SecurityManager - PullRequest
4 голосов
/ 05 февраля 2011

В Java, когда существует SecurityManager, который отклоняет подавление проверки доступа, метод newInstance конструктора работает, в то время как newInstance класса генерирует исключение SecurityException.Вот пример:

import java.lang.reflect.ReflectPermission;
import java.security.Permission;

public class Test {
    public static void main(String[] args) throws Exception {
        System.setSecurityManager(new SecurityManager() {
            @Override
            public void checkPermission(Permission perm) {
                if (perm instanceof ReflectPermission && "suppressAccessChecks".equals(perm.getName())) {
                    throw new SecurityException();
                }
            }
        });

        String.class.getConstructor().newInstance(); // works
        String.class.newInstance(); // throws SecurityException
    }
}

Запуск этого приводит к:

Exception in thread "main" java.lang.SecurityException
    at Test$1.checkPermission(Test.java:10)
    at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:125)
    at java.lang.Class$1.run(Class.java:351)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.lang.Class.newInstance0(Class.java:348)
    at java.lang.Class.newInstance(Class.java:325)
    at Test.main(Test.java:16)

JavaDoc для Class.newInstance говорит, что он вызывает checkMemberAccess и checkPackageAccess на SecurityManager, ноЯ не знаю, почему это вызвало бы setAccessible .Есть ли смысл в такой разнице в поведении?

Я использую:

java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.5) (ArchLinux-6.b20_1.9.5-1-x86_64)
OpenJDK 64-Bit Server VM (build 17.0-b16, mixed mode)

1 Ответ

0 голосов
/ 05 февраля 2011

Class.newInstance() вызывает SecutrityManager.checkMemberAccess(this, Member.PUBLIC), который - по умолчанию - предоставляет доступ всем публичным участникам. checkPermission() вызывается (checkMemberAccess()), только если рассматриваемый член не public.

Таким образом, ваше переопределение checkPermission() не повлияет на доступ к публичным участникам. Вам нужно переопределить checkMemberAccess().

Вот соответствующие цитаты из Javadocs Класс :

(newInstance() сбой, если) вызов s.checkMemberAccess (this, Member.PUBLIC) запрещает создание новых экземпляров этого класса

И из SecurityManager :

Политика по умолчанию (checkMemberAccess()) - разрешить доступ к членам PUBLIC, а также доступ к классам, которые имеют тот же загрузчик классов, что и вызывающая сторона. Во всех остальных случаях этот метод вызывает checkPermission () ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...