1

This Question answers on handling abstract method types; but how to proxy the non-abstract portion of the methods? Implementing abstract methods at runtime?

How can I execute the following to call sayHello()?

package cglibtest;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CGLibTest
{
    public static void main(String... args)
    {
        MyAbstract instance = (MyAbstract)Enhancer.create(MyAbstract.class, new MyInterceptor(42));
        System.out.println("Value from instance: " + instance.valueMethod());
        System.out.println("Value from instance: " + instance.sayHello());
    }

    public static class MyInterceptor implements MethodInterceptor
    {
        private final Object constantValue;

        public MyInterceptor(Object constantValue)
        {
            this.constantValue = constantValue;
        }

        @Override
        public Object intercept(Object obj, Method method, Object[] args,
                MethodProxy proxy) throws Throwable
        {
            if ("valueMethod".equals(method.getName()))
                return(constantValue);
            else
                return(null);
        }
    }

    public static abstract class MyAbstract
    {
        public abstract int valueMethod();
         public String sayHello() { return "Hello" };
    }
}
Community
  • 1
  • 1
Njax3SmmM2x2a0Zf7Hpd
  • 1,354
  • 4
  • 22
  • 44
  • Someone asked the same question as you. I Google'd it up and found [this](http://stackoverflow.com/questions/8722407/how-to-call-abstract-class-method-in-java) as the first result. Check the answer there and your problem would be solved. Good luck. – ihsan Aug 11 '14 at 13:13

1 Answers1

1

The interceptor you have created does already override all methods, regardless of being abstract or not. What you seem to have missed is how to invoke the original method that you have overridden:

public Object intercept(Object obj, Method method, Object[] args,
        MethodProxy proxy) throws Throwable
{
    if ("valueMethod".equals(method.getName()))
        return constantValue;
    else if("sayHello".equals(method.getName())) {
        System.out.println("before original sayHello()");
        // equivalent of saying super.sayHello() inside subclass
        Object result=proxy.invokeSuper(obj, args);
        System.out.println("after original sayHello()");
        return result;
    }
    else return null;
}
Holger
  • 285,553
  • 42
  • 434
  • 765
  • if I happen to have multiple abstract classes any ideas how may I forward them ? – Njax3SmmM2x2a0Zf7Hpd Aug 11 '14 at 14:45
  • 1
    I’m not sure what you are asking. In Java you can only extend from one `abstract` class. But you can implement multiple interfaces; cglib reflects that by providing an alternative `Enhancer.create` method accepting an array of interface `Class`es. But you can create different proxies for different `abstract` classes using only one interceptor implementation; in this case, as far as I understood, the `MethodProxy` which get passed to your `intercept` method will always be suitable to the currently invoked method. But of course, you can always implement multiple different interceptors. – Holger Aug 11 '14 at 15:18