简体   繁体   English

使用SecurityManager的Constructor.newInstance vs Class.newInstance

[英]Constructor.newInstance vs Class.newInstance with a SecurityManager

In Java, when a SecurityManager exists that rejects access check suppression, Constructor's newInstance method works while Class's newInstance throws a SecurityException. 在Java中,当存在拒绝访问检查抑制的SecurityManager时,Constructor的newInstance方法可以工作,而Class的newInstance会抛出SecurityException。 Here's an example: 这是一个例子:

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
    }
}

Running this produces: 运行它会产生:

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)

The JavaDoc for Class.newInstance says that it calls checkMemberAccess and checkPackageAccess on the SecurityManager, but I don't know why it would call setAccessible . Class.newInstance的JavaDoc说它在SecurityManager上调用checkMemberAccess和checkPackageAccess,但我不知道为什么它会调用setAccessible Is there a rationale for this difference in behavior? 这种行为差异有没有理由?

I'm using: 我正在使用:

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)

Class.newInstance() invokes SecutrityManager.checkMemberAccess(this, Member.PUBLIC) , which - by default - grants access to all public members. Class.newInstance()调用SecutrityManager.checkMemberAccess(this, Member.PUBLIC) ,默认情况下授予对所有公共成员的访问权限。 checkPermission() is called (by checkMemberAccess() ) only if the member in question is not public . 只有当有问题的成员公开时,才会调用checkPermission() (通过checkMemberAccess() )。

Thus, your overriding of checkPermission() will not affect access to public members. 因此,覆盖checkPermission()不会影响对公共成员的访问。 You need to override checkMemberAccess() . 您需要覆盖checkMemberAccess()

Here are the relevant quotes from the Javadocs of Class : 以下是Javadocs of Class的相关引用:

( newInstance() fails if) invocation of s.checkMemberAccess(this, Member.PUBLIC) denies creation of new instances of this class newInstance()失败,如果)调用s.checkMemberAccess(this,Member.PUBLIC)拒绝创建此类的新实例

And of SecurityManager : SecurityManager

The default policy (of checkMemberAccess() ) is to allow access to PUBLIC members, as well as access to classes that have the same class loader as the caller. 默认策略( checkMemberAccess() )是允许访问PUBLIC成员,以及访问与调用者具有相同类加载器的类。 In all other cases, this method calls checkPermission() ... 在所有其他情况下,此方法调用checkPermission() ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM