Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Javanica: HystrixCommandAspect not able to get generic class type #784

Closed
vibhaanshu opened this issue May 2, 2015 · 5 comments
Closed

Comments

@vibhaanshu
Copy link

I'm using hystrix command on a class which is implementing generic interface. HystrixCommandAspect is not able to retrieve the parameter types of the child class.

public interface IHelloComponent <K, T>{  
        public String getValue(final K key, final T value);
        public String defaultValue(final K key, final T value);
    }

@Service
public class HelloComponent implements IHelloComponent<String, String>{
    @Override
    @HystrixCommand(fallbackMethod = "defaultValue")
    public String getValue(final String key, final String value){
        if(true)
        throw new RuntimeException();
        return "Hello";
    }
    public String defaultValue(final String key, final String value){
        return "default";
    }

Inside HystrixCommandAspect Method value is coming as public java.lang.String HelloComponent.getValue(java.lang.Object,java.lang.Object). Because of this it throws error hystrixCommand cannot be null.

@mattrjacobs mattrjacobs changed the title HystrixCommandAspect not able to get generic class type Javanica: HystrixCommandAspect not able to get generic class type May 4, 2015
fabcipriano added a commit to fabcipriano/exercises that referenced this issue Sep 6, 2015
@mattrjacobs
Copy link
Contributor

@dmgcodevil Any thoughts on this one?

@dmgcodevil
Copy link
Contributor

Not so far but I'll check it.
On 15 Oct 2015 12:39 p.m., "Matt Jacobs" notifications@github.com wrote:

@dmgcodevil https://github.com/dmgcodevil Any thoughts on this one?


Reply to this email directly or view it on GitHub
#784 (comment).

@dmgcodevil
Copy link
Contributor

@vibhaanshu you have this problem because you use JDK proxy in spring. Actually if you have interface for bean then spring automatically creates proxy using JDK, otherwise cglib. Proxy created using jdk doesn't have information about annotations. You should use cglib proxies instead of jdk.

Spring creates proxies and by default JDK Dynamic Proxies, it basically creates a dynamic class a boottime (those nice $Proxy42 classes) which act like instances of your interfaces. If you now call get class you will get that dynamically created classes that doesn't have your annotations.

@vibhaanshu
Copy link
Author

Thanks

@dmgcodevil
Copy link
Contributor

@vibhaanshu hold on. I was convinced that javanica works fine with jdk proxy and I'm sure that I did some work to have it works. ProceedingJoinPoint has two methods: getThis() returns proxy, but getTarget() returns real object and we can get real type. So jdk proxies shouldn't be a problem but it is not true and let me explain why .I spent couple hours to figure out. I found the root cause of the issue. Java creates bridge methods for methods with generics (I forgot about that...):

public static Class[] getParameterTypes(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        return method.getParameterTypes();
    }

this code returns paramter types for bridge method and results to array with raw types, i.e. array Objects.
Calling java type.getDeclaredMethod(methodName, parameterTypes); returns bridge method that doesn't have any annotations. It happens because we need to pass generic types to get appropriate method but not raw types. I added the ability to get original method instead of bridge and now it works now. Created PL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants