0

I'm having problems implementing a Proxy for a class that has to print the stacktrace for every call on a function of a class, because the functions are nested one with the other.

The problem is very similar if not the same to one another user had, the answers helped me to understand how to approach it but still I can't manage to solve it ( Dynamic Proxy: how to handle nested method calls ).

I've a class :

public class NestedCalls implements INestedCalls{
    private int i = 0;
    public int a() {
        return b(i++); 
    }
    public int b(int a) {
        return (i<42)?c(b(a())):1;
    }
    public int c(int a) {
        return --a;
    }
}

and its interface:

public interface INestedCalls {
    public int a() ;
    public int b(int a) ;
    public int c(int a) ;
}

The handler I implemented looks like this:

public class NestHandler implements InvocationHandler {

    Object base;

    public NestHandler(Object base) {
        this.base=base;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(base, args);      
       printNest();
       return result;
    }   

    private void printNest() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
        StackTraceElement[] stack = new Throwable().getStackTrace();
        System.out.println("num of elem " + stack.length);
        for(int i=0; i<stack.length; i++) {
            System.out.println("elem "+i+": "+stack[i]);
        }
    }

}

What I aim to do is to initialize the object and the proxy from my main and after invoking a method I expect to print the stacktrace every time a method of the class is invoked.

    INestedCalls nestedcalls = new ENestedCalls();      
    INestedCalls nestproxy = (INestedCalls) Proxy.newProxyInstance(nestedcalls.getClass().getClassLoader(), nestedcalls.getClass().getInterfaces(), new NestHandler(nestedcalls));      
    nestproxy.a();

To my understanding this doesn't work because the proxy handles everything with a intra-object and so the nested methods are not called with the proxy interface.

How can I get the effect I want without touching the code of the class?

LowRez
  • 125
  • 2
  • 14
  • That code should work just fine. – Sotirios Delimanolis Nov 22 '18 at 18:46
  • The code itself works but not in the way I imagined. What I would like to do is to have the invoke function to print the stack even when b(int a) and c(int a) are called from nestproxy.a(), but it prints only once. – LowRez Nov 22 '18 at 19:23
  • Oh you can't do that easily. You'd have to always go through the proxy, instead of directly calling `this.b(...);`. You might want to look into AspectJ's AOP implementation for a "better" solution. – Sotirios Delimanolis Nov 22 '18 at 19:48
  • Thanks for the answer. I had a look at AspectJ and it should be the best way to solve this problem, however I was wondering if it was possible without using it. I thought about extending my NestedCalls class and to override the methods in a way that they would call the proxy but I can't manage to write a code that works or goes in a loop. – LowRez Nov 23 '18 at 11:10

0 Answers0