3

Consider the following 2 controllers written using Play Framework 2.3.8:

Java8 lambdas:

public static Promise<Result> testLambda() {
    final Promise<Boolean> promiseBool = Promise.promise(() -> "TEST".equals("test"));

    return promiseBool.map(bool -> ok()).recover(t -> badRequest());
}

"Normal":

public static Promise<Result> test() {
    final Promise<Boolean> promiseBool = Promise.promise(new Function0<Boolean>() {
        @Override
        public Boolean apply() throws Throwable {
            return "TEST".equals("test");
        }
    });

    return promiseBool.map(new Function<Boolean, Result>() {
        @Override
        public Result apply(Boolean bool) throws Throwable {
            return ok();
        }
    }).recover(new Function<Throwable, Result>() {
        @Override
        public Result apply(Throwable t) throws Throwable {
            return badRequest();
        }
    });
}

The controller written using lambdas gives me this ERROR in eclipse: Type mismatch: cannot convert from F.Promise<Results.Status> to F.Promise<Result> while the second one doesn't. This happens only when using the recover() function.

On the other hand, sbt compiles the code without complaining.

Question: Why is this happening and how can it be fixed?



For others searching for a -> REASON:

Based on Salem's answer and this answer: This is an Eclipse bug and has nothing to do with type inference or other <insert you favourite Java bashing here>.

Community
  • 1
  • 1
sebster
  • 1,322
  • 2
  • 18
  • 29

1 Answers1

2

There was a bug related to this in Play Framework but from the discussion it seems that this is more a problem of Java than Play itself. The workaround would be something like this (credit to igmar):

return promiseBool.map(new Function<Boolean, Result>() {
    @Override
    public Result apply(Boolean bool) throws Throwable {
        Result res = ok();
        return res;
    }
}).recover(new Function<Throwable, Result>() {
    // Same
});

Using return (Result) ok(); may also work.

Salem
  • 12,808
  • 4
  • 34
  • 54
  • 1
    If that works, `bool -> (Result)ok()` should work as well, shouldn’t it? But it’s the first time I hear that Java should have problems with covariant return types. I can understand, if it’s an Eclipse issue as it has plenty of problems with Java 8 but blaming Java in general looks like a thin claim. Maybe it would help to know where the `ok()` method does come from and how its signature looks like… – Holger Mar 31 '15 at 11:31
  • Indeed (Result) ok() works as well. You might be right about the Java bashing... will investigate and return with an update if I find something. – sebster Mar 31 '15 at 15:02
  • On the other hand we can blame the type inference in Java as a whole. Not the sharpest pencil... – sebster Mar 31 '15 at 15:04
  • Investigated -> added reason to my question. Maybe you can add it to your answer as well. Redundancy FTW! – sebster Apr 01 '15 at 16:19