2011-02-05 5 views
4

Javaでは、アクセスチェックの抑制を拒否するSecurityManagerが存在する場合、ClassのnewInstanceがSecurityExceptionをスローする間、ConstructorのnewInstanceメソッドが機能します。ここでは例です:Constructor.newInstanceとSecurityManagerを持つClass.newInstance

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

が、これは生産の実行:Class.newInstanceため

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はそれがセキュリティマネージャ上のcheckMemberAccessとcheckPackageAccessを呼び出しますが、それは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) 
+0

コード/コメントを読もうとしましたか?これはなぜそれが何をするのかを示すかもしれません。 –

+0

私はOpenJDKのClass.javaを見て、setAccessible呼び出しの直前にこのコメントを見つけました。 "コンシューマー のアクセシビリティチェックを無効にします。ここではセキュリティチェックを行う必要があるので、ここで セキュリティチェックが機能します)。 " 私は外部からの違いがある理由はまだ分かりません。 –

+0

コメントはよく説明されていますが、私にはバグのように見えます。この例外は単純に無視できます。setAccessibleが失敗した場合、既にアクセス可能でnewInstanceが機能していないか、newInstanceが機能しません。どちらも正しいので、例外は無視されても問題ありません。 – maaartinus

答えて

0

Class.newInstance()SecutrityManager.checkMemberAccess(this, Member.PUBLIC)、呼び出し - デフォルトで - 助成金は、すべてのパブリックメンバへのアクセスを。 checkPermission()は、問題のメンバーがではなく、公開の場合にのみ(checkMemberAccess()によって)呼び出されます。

したがって、checkPermission()のオーバーライドはパブリックメンバーへのアクセスに影響しません。 checkMemberAccess()を上書きする必要があります。ここで

が関連 ClassのJavadocのからの引用です:

newInstance()があれば失敗)s.checkMemberAccess(この、Member.PUBLICを)の呼び出しは、このクラスの新しいインスタンスの作成を拒否し

そしてSecurityManagerの:(checkMemberAccess()の)

デフォルトポリシーはPUBLへのアクセスを可能にすることですICメンバ、呼び出し元と同じクラスローダを持つクラスへのアクセスなどがあります。それ以外の場合は、checkPermission()を呼び出します。 ...

+0

私は恐れている、あなたはポイントを逃した。 OPはpublicであり、常に成功するはずですが、セキュリティ設定が与えられた 'Class.newInstance()'で失敗する 'new String()'と同等です。 – maaartinus

関連する問題