-2

I am using Spring RetryTemplate and using this method. Wanted to pass some argument (vendor) it is giving me compilation error. I can create a another variable vendorName as final can send it. But I want to make use the the variable vendor. It must be simple one but not getting it. please help.

public Token getToken(final String tokenId) {
    String vendor = getVendor(tokenId);//returns some vendor name
    RetryTemplate retryTemplate = getRetryTemplate();
    Token token = retryTemplate.execute(context -> {
        logger.info("Attempted {} times", context.getRetryCount());
        return retrieveToken(tokenId, vendor);
    });
}

private RetryTemplate getRetryTemplate() {

    final FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
    fixedBackOffPolicy.setBackOffPeriod(getRandomNumber() * 1000);

    final SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
    retryPolicy.setMaxAttempts(5);

    final RetryTemplate retryTemplate = new RetryTemplate();
    retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
    retryTemplate.setRetryPolicy(retryPolicy);

    return retryTemplate;
}

compilation error is: Local variable vendor defined in an enclosing scope must be final or effectively final

Eamon Scullion
  • 1,354
  • 7
  • 16
Kiran
  • 839
  • 3
  • 15
  • 45

2 Answers2

1

Prior to Java 8, we cannot use a non-final local variable in an anonymous class. It's very useful in the context of the lambda expression as well. Please check below link Java Lambda Expression with Non-final Function Paramter

Better to modify your code

public Token getToken(final String tokenId) {
    final String vendor = getVendor(tokenId);//returns some vendor name
    RetryTemplate retryTemplate = getRetryTemplate();
    Token token = retryTemplate.execute(context -> {
        logger.info("Attempted {} times", context.getRetryCount());
        return retrieveToken(tokenId, vendor);
    });
}

Or Assign vendor value in another final variable.

Ashutoshg
  • 157
  • 1
  • 7
0

You cannot use non-final variables in a lambda.

One option is to set vendor to final

Alternatively, you can refactor to just use a for loop instead.

Eamon Scullion
  • 1,354
  • 7
  • 16
  • I can not set because i have some logic based on that i am setting vendor. I can create another variable as final to use. But I want to pass existing instead of creating a new one. – Kiran Nov 08 '18 at 23:58
  • 1
    @Kiran then you'll have to copy it to a variable that is final. There is no way around this. – Louis Wasserman Nov 08 '18 at 23:59
  • @LouisWasserman okay. I was thinking we can pass a variable. If that is the only option then i will do. thanks – Kiran Nov 09 '18 at 00:00