Reputation: 1
given the following Java8 code, how can this be implemented in Java11 ?
The checkMemberAccess()
method has been replaced with the new checkPermission()
method.
Java 8 code:
SecurityManager securityManager = System.getSecurityManager();
securityManager.checkMemberAccess(SomeClass.class, Member.DECLARED);
I want to make sure that we can't call java.lang.Class#getDeclared*() on SomeClass
I know that Java11 now has a SecurityManager.checkPermission()
method, the question is, how do I use this on a specific class in order to check whether or not I have "accessDeclaredMembers"
permission.
I have found this similar question, but it doesn't tell me much.
Upvotes: 0
Views: 174
Reputation: 298123
You wrote
I know that Java11 now has a
SecurityManager.checkPermission()
method…
but this method exists since Java 2, also known as “JDK 1.2”. Since then, the other check…
methods existed for backwards compatibility only and delegate to the checkPermission
method. Consistently, the documentation of the checkMemberAccess
method contains the following description since Java 2:
The default policy is to allow access to PUBLIC members, as well as access to classes that have the same class loader as the caller. In all other cases, this method calls
checkPermission
with theRuntimePermission("accessDeclaredMembers")
permission.
which tells you precisely what you would have to do when you want to have the same logic without calling this method.
securityManager.checkPermission(new RuntimePermission("accessDeclaredMembers"));
except for the already documented quirks, like always accepting the access when the caller at a stack depth of 4 happens to have the same class loader as the target class. Note further that this Java 8 version contains a deprecated warning describing the problems.
So the bigger question is what you want to achieve with the call. You wrote
I want to make sure that we can't call java.lang.Class#getDeclared*() on SomeClass
But this method doesn’t “make sure” that, whoever “we” is, can’t access the members, it only checks whether the current caller (at a stack depth of 4) can access that method for the specified class.
To make sure that this access is not possible, you would have to make sure that the potential caller has been loaded by a different class loader (as the documentation says, classes loaded by the same class loader always get the access). Then, you have to configure a security manage to revoke the RuntimePermission("accessDeclaredMembers")
. Since you where not aware about the relationship between checkMemberAccess
and that permission, I suppose you never did this.
Before trying to actually use a security manager to prevent that access (if possible at all in your project setup), I have to warn you that you’d be riding a dead horse then. JDK 17 is going to deprecate the entire SecurityManager
for removal. Restricting code activities in this way is going to be removed.
Upvotes: 1