How to restrict developers to use reflection to access private methods and constructors in Java?
Using normal Java code we can't access private constructors or private methods outside of a class. But by using reflection we can access any private methods and constructors in a Java class.
So how can we give security to our Java code?
Run your application using a SecurityManager
and a sufficiently restrictive security policy.
There's a short summary in the tutorial and extensive information in the security documentation.
Add checkPermission()
method in all of your private method/constructor.
checkPermission using sun.reflect.Reflection.getCallerClass(int n)
by assert callerClass=selfClass
.
The getCallerClass
returns the class of the method realFramesToSkip
frames up the stack (zero-based), ignoring frames associated with java.lang.reflect.Method.invoke()
and its implementation. The first frame is that associated with this method, so getCallerClass(0)
returns the Class object for sun.reflect.Reflection
.
public class PrivateConstructorClass {
private PrivateConstructorClass() {
checkPerMission();
//you own code go below
}
void checkPerMission() {
Class self = sun.reflect.Reflection.getCallerClass(1);
Class caller = sun.reflect.Reflection.getCallerClass(3);
if (self != caller) {
throw new java.lang.IllegalAccessError();
}
}
}
You can try to test reflect, it will fail:
public class TestPrivateMain {
Object newInstance() throws Exception {
final Class<?> c = Class.forName("package.TestPrivate");
final Constructor<?> constructor = c.getDeclaredConstructor();
constructor.setAccessible(true);
return constructor.newInstance();
}
public static void main(String[] args) throws Exception {
Object t = new TestPrivateMain().newInstance();
}
}
You (as the developer of the code in question) cannot do that.
The end user, who runs the application, could install a SecurityManager that forbids reflection.