Code Monkey home page Code Monkey logo

Comments (8)

artembilan avatar artembilan commented on June 11, 2024

See the test provided for that fix:

	private static class ParameterTest<T, M> {

		List<T> m1() {
			return null;
		}

		List<T> m2() {
			return null;
		}

		List<M> m2_1() {
			return null;
		}
...

		assertThat(isParameterizedTypeAssignable.invoke(null, getGenericReturnTypeByName("m1"),
				getGenericReturnTypeByName("m2"))).isEqualTo(Boolean.TRUE);
		assertThat(isParameterizedTypeAssignable.invoke(null, getGenericReturnTypeByName("m2"),
				getGenericReturnTypeByName("m2_1"))).isEqualTo(Boolean.FALSE);

So, since T is exposed on a class by itself, it is indeed the same type on those methods, but M is not equal to T.
In this case:

class MyClass {
   
		<T> List<T> m1() {
			return null;
		}

		<T> List<T> m2() {
			return null;
		}
}

Ts are really different because they are local to the methods they are declared on.
It is no difference with any local variables even if they have the same name.

from spring-retry.

bgiaccio avatar bgiaccio commented on June 11, 2024

So basically I have

public class MyClass {
    	@Retryable(value = {Throwable.class}, exclude = { NotAcceptableException.class }, backoff = @Backoff(delay = 1000, multiplier = 2), maxAttemptsExpression = "5")
	@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Throwable.class)
	public <T> List<T> runQuery( Class<T> returnType, otherArgs ) { ...}

	@Recover
	private <T> List<T> recoverRunQuery(Exception ex, Class<T> returnType, otherArgs ) throws Exception { ... }

With spring-recover 2.0.0 that worked just fine but it fails with 2.0.4 which I've traced back to #328

This class is a helper for fetching data from numerous classes so T varies by the caller, so creating an instance for each would be a substantial code change. Hoping you have a suggestion on how I might make a recover method for that.

from spring-retry.

artembilan avatar artembilan commented on June 11, 2024

You just relied on a bug or rather some side-effect which didn't honor generics.
If you still insist on using those local <T>, then consider to use this attribute on the @Retryable:

	/**
	 * Name of method in this class to use for recover. Method had to be marked with
	 * {@link Recover} annotation.
	 * @return the name of recover method
	 */
	String recover() default "";

instead of trying to trick reflection which we treat as a bug and therefore the fix you are mentioning.

from spring-retry.

swampy2b avatar swampy2b commented on June 11, 2024

We did try with setting the recover attribute in the @Retryable annotation, but it had no effect, because the method was never added to list of potential recovery methods due to the return type mismatch.

from spring-retry.

bgiaccio avatar bgiaccio commented on June 11, 2024

So using the recover attribute on the annotation selects the method but when trying to mach it winds up back in isParameterizedTypeAssignable passing sun.reflect.generics.reflectiveObjects.TypeVariableImpl but fails because methodArgType.equals(failingMethodArgType) is false

from spring-retry.

artembilan avatar artembilan commented on June 11, 2024

How about to make your @Recover method as Object for return type (if something like List<?> doesn't work)?

My point is that we need to agree that <T> List<T> is local declaration and according to Java it is really not equal on different methods.

from spring-retry.

bgiaccio avatar bgiaccio commented on June 11, 2024

I wound up reworking the code to use https://github.com/spring-projects/spring-retry#using-recoverycallback
Small documentation issue on that page it should be Foo foo = template.execute(new RetryCallback<Foo, Exception>() {

So in case someone else is reading this bug the solution looks like

retryTemplate = RetryTemplate.builder()
	.maxAttempts(maxAttempts)
	.notRetryOn(List.of(NotAcceptableException.class, InstantiationException.class))
	.customBackoff(BackOffPolicyBuilder.newBuilder().delay(delay).multiplier(multiplier).build())
	.build();
return retryTemplate.execute(
	(RetryCallback<List<T>, Exception>) context -> self.retryRunQuery(queryName, returnType, otherArgs),
	context -> self.recoverQuery(context.getLastThrowable(), queryName)
);

from spring-retry.

artembilan avatar artembilan commented on June 11, 2024

Thank you for feedback!

Those docs are fixed now.

from spring-retry.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.