Today I was to this Seam presentation by David Geary, and it was the first time I was actually seeing an EJB 3 code in which I pointed out Seam is magically (k, I mean using reflection) setting private members of a bean class. This was the first time I had to think if that is actually possible. Guess what? Yes it is possible.
Consider this example:
package test; public class TestClass { private int a = 2; public void printA() |
TestClass has a private in member and a method to print the private data out. My goal is to access this private memeber's value through reflection. A quick and dirty try to do so would be a code like this:
import java.lang.reflect.Field; public class TestReflection { public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { TestClass t = new TestClass(); a.setInt(t, 14); |
Running this will run into a java.lang.IllegalAccessException exception, which is what you would expect. However, the trick to access a private member's value is to set its accessibility. The Field class has a setAccessible method by which you can tell the VM I want to set this field's value. So, adding a single line to the same code will do the job:
import java.lang.reflect.Field; public class TestReflection { public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { TestClass t = new TestClass(); a.setAccessible(true); a.setInt(t, 14); |
Installing a security manager will prevent setting a field's accessiblity. However, you still have the option to let a specific code base do it. Yes, I am talking about security policy files. In other words, there is ways to get around this anyways.
In any events, I am not sure if this is only my illusion that private fields are not really private or there is a way to secure private values.
No comments:
Post a Comment