Convert Java code to Scala

I am a scala beginner and need some help to convert the below java “retrywhen” to scala.

Observable.merge(observables).retryWhen(errors -> errors.flatMap(error -> {
if (error instanceof IOException) {
return Observable.just(null);
}
// For anything other than IOException, don’t retry
return Observable.error(error);
})
)

I tried as below but gives me “missing parameter type” for “flatmap”.

Observable.merge(observables).retryWhen((errors: Observable[_ <: Throwable]) => errors.flatMap(error => if (isInstanceOf[IOException]) Observable.just(null) else Observable.error(error) ))

Thank you.

First, a few suggestions for creating posts like this:

  • Put code blocks inside “```” (triple backticks) to improve readability.
  • Reference libraries you are using (where does Observable come from?) and provide type information for identifiers originating outside the quoted code (what is observables?).
  • Quote error messages verbatim.

Assuming you’re using RxJava 2 and observables is a Java Iterable<Observable<T>> for whatever concrete T, I cannot reproduce any compiler error with your version.

A slightly more idiomatic Scala version:

Observable.merge(observables).retryWhen(_.flatMap {
    case _: IOException => Observable.just(null)
    case error => Observable.error(error)
  }
)

(No guarantees for correctness - I don’t know RxJava and haven’t tested this.)

However, I’d strongly suggest to trace back a few steps for a variety of reasons.

  • It’s easier to familiarize yourself with Scala via a text book and small pieces of standalone code before attempting to convert legacy Java code.
  • There’s better, Scala-native choices for reactive streams libraries than RxJava: akka-streams, Monix,…
  • You’ll want to get rid of Java residue (like null usage and Java collections just in this snippet), so a port from Java will always turn out to be a complete overhaul or even rewrite rather than a faithful translation.
2 Likes

Thank you. I see the below error when compiling your and my version.

missing parameter type for expanded function ((x$1) => x$1.flatMap( match {
case (_: IOException) => Observable.just(null)
case (error @ _) => Observable.error(error)

Then you’ll have to provide an SSCCE so others can reproduce your problem. This should include at least a standalone source code file and the library dependencies (from your build.sbt or whatever build tool you’re using).

I’d still strongly suggest to take a different approach to Scala than trying to convert Java code based on a rather advanced library whose Scala binding has recently been abandoned in favor of other alternatives.

1 Like

Apologies - I just reopened the project where I tried this, and I’m seeing the same error. :confused: No idea why I hadn’t seen it the last time, maybe I trusted the presentation compiler and didn’t force a full build.

I can’t formally explain the cause of the problem, but I guess the compiler gets lost in the mix of overloads, Java wildcards and custom functional interfaces. Explicitly providing the right Function type for the #flatMap() application seems to do the trick.

val retryError: io.reactivex.functions.Function[Throwable, ObservableSource[String]] = {
  case _: IOException => Observable.just(null)
  case error => Observable.error(error)
}

Observable.merge(observables.asJava).retryWhen(_.flatMap(retryError))

…but I guess this serves to illustrate why I don’t think it’s a good idea to move on with a faithful translation of this Java code…