Java prevents private or protected methods from being called outside the class

Suppose I created a Java library called Foo , and I have a class inside a library called Bar . Suppose further that in the Bar class, I have a private method called fooBar .

 public class Bar { //... private Object fooBar() { //Do something } //... } 

You can run this method without any difficulty with code written in the class, for example:

 public static Object runMethod(Object object, String methodName) { Method method = object.getClass().getDeclaredMethod(methodName); method.setAccessible(true); return method.invoke(object); } 

However, suppose we intend to discourage this habit for fooBar . How can we do something like this? Should we get a stack trace from somewhere and check where it was called? Or should we do something else?

+5
source share
2 answers

You need a security manager ...

https://docs.oracle.com/javase/tutorial/essential/environment/security.html

A security manager is an object that defines the security policy for an expression. This policy defines actions that are unsafe or sensitive. Any actions not permitted by the security policy raise a SecurityException. An application may also request it to determine what actions are allowed.

It supports the prohibition of setAccessible() to make private and protected methods invocable through reflection.

+6
source

I think if you want to be extreme, you can get a stack trace as follows:

 public class Bar { //... private Object fooBar() { try { throw new CheckIfCalledFromMethodException(); } catch(CheckIfCalledFromMethodException e) { //here you have access to stack trace in your exception } //Do something } //... } 

I put together a simple script in which it checks if the second instance that calls the class is the same object or something else.

 public class StackTraceTest { private void execute() { try { throw new Exception(); } catch (Exception e) { /*for(int i = 0; i < e.getStackTrace().length; i++) { StackTraceElement stackTraceElement = e.getStackTrace()[i]; System.out.println(stackTraceElement.getFileName()); } System.out.println(""); e.printStackTrace();*/ if(!e.getStackTrace()[1].getFileName().equals(StackTraceTest.class.getSimpleName() + ".java")) { throw new IllegalAccessError("Illegal Access."); } } } public void executeExternal() { this.execute(); } } 

and

 public class AccsessorTest { public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { StackTraceTest stackTraceTest = new StackTraceTest(); stackTraceTest.executeExternal(); System.out.println("Accessed from within other method in class."); System.out.println(""); Class<?> clazz = StackTraceTest.class; Method method = clazz.getDeclaredMethod("execute"); method.setAccessible(true); System.out.println("Accessing through reflection..."); method.invoke(stackTraceTest); } } 

Then i get

 Accessed from within other method in class. Reflection test start. Accessing through reflection... Exception in thread "main" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at stacktracetest.another.AccsessorTest.main(AccsessorTest.java:22) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134) Caused by: java.lang.IllegalAccessError: Illegal Access. at stacktracetest.StackTraceTest.execute(StackTraceTest.java:18) ... 10 more 

So, I think you can check with the magic of the stack trace element, but you have to check if this really works, this is very rude, and I just compiled it a second time.

+3
source

All Articles