1

A Scala code has a retry mechanism which is based on currying function:

object RetryUtil {

  def retry[T](retry: Int, timeout: FiniteDuration)(exc: => T): T = {
  //
  }
}

I want to call this code from Java (8), which use generics:

public class SuperService {

    public <T> T call(Data<T> data) {
     // I want to call internalCall from here, with the Scala retry mechanism from before.
    }

    private <T> T internalCall(DataWithResult<T> data) {
    }
}

How should it be done?

Thanks.

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
Johnny
  • 14,397
  • 15
  • 77
  • 118
  • 2
    `.apply`, I believe. Decompile the bytecode and see for yourself, if you're ever unsure of how Scala code gets desugared. – user Nov 03 '20 at 15:48

1 Answers1

4

For

private <T> T internalCall(TransactionWithResult<T> data) {
  return null;
}

private void internalCall2(TransactionWithoutResult data) {
}

try

public <T> T call(Data<T> data) {
  RetryUtil.retry(3, new FiniteDuration(1, TimeUnit.MINUTES), () -> { internalCall2(data); return null; });

  return RetryUtil.retry(3, new FiniteDuration(1, TimeUnit.MINUTES), () -> internalCall(data));
}

Parameters from multiple parameter lists in Scala should be seen in Java as parameters of a single parameter list.

Scala and Java functions should be interchangeable (since Scala 2.12)

How to use Java lambdas in Scala (https://stackoverflow.com/a/47381315/5249621)

By-name parameters => T should be seen as no-arg functions () => T.

I assumed that Data implements TransactionWithResult and TransactionWithoutResult, so Data can be used where TransactionWithResult or TransactionWithoutResult is expected, otherwise the code should be fixed.

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
  • Thanks! And if the method I want to have retry with, `internalCall`, returns `void`? – Johnny Nov 03 '20 at 16:38
  • Just to elaborate - I have an additional method like `internalCall`, let's call it `internalCall2`, that defined as `private void internalCall(DataWithoutResult data)`, and I need to call it with the retry as well, but it expects to return the `T`. What is the most elegant way to overcome it? Thanks. – Johnny Nov 03 '20 at 16:58
  • 1
    @Johnny Try `RetryUtil.retry(3, new FiniteDuration(1, TimeUnit.MINUTES), () -> { internalCall2(data); return null; });`. And then `return null;` if necessary. – Dmytro Mitin Nov 03 '20 at 17:04