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

[code error] in org.springframework.retry.annotation.RecoverAnnotationRecoveryHandler#isParameterizedTypeAssignable #328

Closed
lijinliangyihao opened this issue Jan 31, 2023 · 2 comments
Labels
Milestone

Comments

@lijinliangyihao
Copy link

Look at the for loop, the first if branch, it only check the first type argument of the ParameterizedType and returned. When there are two type arguments, the result will be wrong.

private boolean isParameterizedTypeAssignable(ParameterizedType methodReturnType,
			ParameterizedType failingMethodReturnType) {

    Type[] methodActualArgs = methodReturnType.getActualTypeArguments();
    Type[] failingMethodActualArgs = failingMethodReturnType.getActualTypeArguments();
    if (methodActualArgs.length != failingMethodActualArgs.length) {
	    return false;
    }
    int startingIndex = 0;
    for (int i = startingIndex; i < methodActualArgs.length; i++) {
	Type methodArgType = methodActualArgs[i];
	Type failingMethodArgType = failingMethodActualArgs[i];
	if (methodArgType instanceof ParameterizedType && failingMethodArgType instanceof ParameterizedType) {
            return isParameterizedTypeAssignable((ParameterizedType) methodArgType,
		            (ParameterizedType) failingMethodArgType);
	}
	if (methodArgType instanceof Class && failingMethodArgType instanceof Class
			&& !failingMethodArgType.equals(methodArgType)) {
            return false;
	}
    }
    return true;
}

Here's the test:

public static void main(String[] args) throws NoSuchMethodException {
    Class<?> clz = RecoverAnnotationRecoveryHandler.class;
    Method m1 = clz.getDeclaredMethod("m1");
    Method m2 = clz.getDeclaredMethod("m2");
    ParameterizedType r1 = (ParameterizedType) m1.getGenericReturnType();
    ParameterizedType r2 = (ParameterizedType) m2.getGenericReturnType();
    System.out.println(isParameterizedTypeAssignable(r1, r2));
}

Map<List<String>, String> m1(){return null;}
Map<List<String>, Integer> m2(){return null;}

and the result is true, incorrect!

I make some correction, here's the code:

private static boolean isParameterizedTypeAssignable(ParameterizedType methodReturnType,
			ParameterizedType failingMethodReturnType) {

    Type[] methodActualArgs = methodReturnType.getActualTypeArguments();
    Type[] failingMethodActualArgs = failingMethodReturnType.getActualTypeArguments();
    if (methodActualArgs.length != failingMethodActualArgs.length) {
	return false;
    }
    int startingIndex = 0;
    for (int i = startingIndex; i < methodActualArgs.length; i++) {
	Type methodArgType = methodActualArgs[i];
	Type failingMethodArgType = failingMethodActualArgs[i];
	if (methodArgType instanceof ParameterizedType && failingMethodArgType instanceof ParameterizedType) {
            if (!isParameterizedTypeAssignable((ParameterizedType) methodArgType,
				(ParameterizedType) failingMethodArgType);
                return false;
	} else if (methodArgType instanceof Class && failingMethodArgType instanceof Class) {
            if (!failingMethodArgType.equals(methodArgType))
	        return false;
	} else
            return false;
    }
    return true;
}

and the result is false, which is correct.

@gaofengIt
Copy link

gaofengIt commented Jan 31, 2023 via email

@artembilan
Copy link
Member

Hey, @lijinliangyihao !

Thanks for looking into this.
Feel free to provide a Pull Request with respective unit tests to confirm the problem and of course the fix to keep existing tests and your new as green.

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

No branches or pull requests

3 participants