I'm totally puzzled - I wrote a class in Java8 SE (less than 10 lines of code) which completely compromises restricted (private) methods using reflection. I find this is very dangerous and question the sense of reflection allowing this.
package reflection;
import java.lang.reflect.Method;
import java.util.Arrays;
public class Reflection {
// Throw 'Throwable' because this method must be totally transparent, doing exactly what the actually called method does:
static public Object call(Object target, String methodName, Object... args) throws Throwable {
// Get the arguments' classes:
Class<?>[] argumentClasses =
Arrays.asList(args)
.stream()
.map(object -> object.getClass())
.toArray(Class[]::new);
Method method = target.getClass().getDeclaredMethod(methodName, argumentClasses);
method.setAccessible(true);
return method.invoke(target, args);
}
}
You can run this tests, which calls private methods - both static and non-static - of another class, Action:
package reflection;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class ReflectionUnitTest {
@Test
public void testCall() throws Throwable {
Action target = new Action();
assertEquals("Something static done!", Reflection.call(target, "doSomethingStatic"));
assertEquals("Something static done with something else!", Reflection.call(target, "doSomethingStatic", "something else"));
assertEquals("Something static done 3 times with something else!", Reflection.call(target, "doSomethingStatic", 3, "something else"));
assertEquals("Something static done 5 times with something else!", Reflection.call(target, "doSomethingStatic", "something else", 5));
assertEquals("Something done!", Reflection.call(target, "doSomething"));
assertEquals("Something done with something else!", Reflection.call(target, "doSomething", "something else"));
assertEquals("Something done 3 times with something else!", Reflection.call(target, "doSomething", 3, "something else"));
assertEquals("Something done 5 times with something else!", Reflection.call(target, "doSomething", "something else", 5));
}
}
package reflection;
public class Action {
static private String doSomethingStatic(){
return "Something static done!";
}
private String doSomethingStatic(String argument) {
return "Something static done with " + argument + "!";
}
private String doSomethingStatic(Integer count, String argument) {
return "Something static done " + count + " times with " + argument + "!";
}
private String doSomethingStatic(String argument, Integer count) {
return "Something static done " + count + " times with " + argument + "!";
}
private String doSomething() {
return "Something done!";
}
private String doSomething(String argument) {
return "Something done with " + argument + "!";
}
private String doSomething(Integer count, String argument) {
return "Something done " + count + " times with " + argument + "!";
}
private String doSomething(String argument, Integer count) {
return "Something done " + count + " times with " + argument + "!";
}
}
My issues:
- To share this knowledge with you
- To ask if anybody can explain why this is possible
Aucun commentaire:
Enregistrer un commentaire