playframework/play-ws

[Enhancement] README.md - Compatibility matrix between play-ws and play framework

KafkaProServerless opened this issue · 1 comments

Are you looking for help?

Yes, for a compatibility matrix between play framework version and this cool project

Play WS Version (2.5.x / etc)

2.4

API (Scala / Java / Neither / Both)

Java

Operating System (Ubuntu 15.10 / MacOS 10.10 / Windows 10)

MacOS 10.1

JDK (Oracle 1.8.0_72, OpenJDK 1.8.x, Azul Zing)

Oracle 1.8.0_72

Library Dependencies

Play 2.4

Expected Behavior

We are maintaining an old play 2.4 framework project.
The project got quite big before it got decommissioned, but now, we would like to bring it back. However, this project is using traditional blocking ws API to return F.Promise.

Now, in 2019, we would like to explore non blocking call, by using
public CompletionStage amazing() {
String url = "someasyncRestAPI";
CompletionStage futureResponse = ws.url(url).setMethod("GET").stream();
CompletionStage<Source<ByteString, ?> > result = futureResponse.thenApply(WSResponse::getBodyAsSource);
return result.thenApply(body -> ok(views.html.index.render()));

In order to have some sort of stream and to return instead CompletionStage / CompletableFuture. With a play 2.7 project it is working perfectly, magic.

However, instead of refactoring our 350 handlers from F.Promise to CompletionStage, and having to re do all regression test a migration will bring, we just wanted to write an adaptor to get the F.Promise from a CompletionStage using:

import play.libs.F;
import java.util.concurrent.CompletableFuture;

public class RxFuture<T> {
    private final CompletableFuture<T> cf;
    public RxFuture(final CompletableFuture<T> cf) {
        this.cf = cf;
    }
    public static <E> F.Promise<E> toPromise(final CompletableFuture<E> obs) {
        return new RxFuture(obs).adopt();
    }

    public F.Promise<T> adopt() {
        F.RedeemablePromise<T> rPromise = F.RedeemablePromise.empty();
        cf.whenCompleteAsync((res, err) -> {
            if (err != null) {
                rPromise.failure(err);
            } else {
                rPromise.success(res);
            }
        });
        return rPromise;
    }
}

However, while it is compiling with no error, we get some runtime errors due to play 2.4 + play-ws 2.0.4.

-- (Running the application, auto-reloading is enabled) ---

[info] p.a.l.c.ActorSystemProvider - Starting application default Akka system: application
[info] p.c.s.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Ctrl+D to stop and go back to the console...)

[warn] application - Logger configuration in conf files is deprecated and has no effect. Use a logback configuration file instead.
[info] p.a.l.c.ActorSystemProvider - Starting application default Akka system: application
[info] play.api.Play - Application started (Dev)
Uncaught error from thread [application-akka.actor.default-dispatcher-2]: play.api.libs.ws.WSConfigParser.<init>(Lcom/typesafe/config/Config;Ljava/lang/ClassLoader;)V, shutting down ActorSystem[application]
java.lang.NoSuchMethodError: play.api.libs.ws.WSConfigParser.<init>(Lcom/typesafe/config/Config;Ljava/lang/ClassLoader;)V
        at play.api.libs.ws.ahc.AhcWSClientConfigFactory$.forConfig(AhcConfig.scala:63)
        at play.libs.ws.ahc.AhcWSClientConfigFactory.forConfig(AhcWSClientConfigFactory.java:28)
        at controllers.HomeController.list(HomeController.java:60)
        at controllers.HomeController.important(HomeController.java:70)
        at router.Routes$$anonfun$routes$1$$anonfun$applyOrElse$1$$anonfun$apply$1.apply(Routes.scala:72)
        at router.Routes$$anonfun$routes$1$$anonfun$applyOrElse$1$$anonfun$apply$1.apply(Routes.scala:72)
        at play.core.routing.HandlerInvokerFactory$$anon$5.resultCall(HandlerInvoker.scala:139)

While it too easy to just say "play 2.4 is too old, please upgrade and close this", while not having a clear compatibility matrix?
A matrix of the versions between play framework and this cool project can help more than one finding its way in this project.

Hey @KafkaProServerless,

Play 2.6 is the when we move play-ws to a standalone repository here. You can see exactly which version Play 2.6.x (or 2.7.x) are using by looking at the Dependencies.scala file there:

https://github.com/playframework/playframework/blob/2.6.23/project/Dependencies.scala#L269

Before that, for Play 2.5-, play-ws must follow the version of Play you are using.

In both cases, you won't have problems if you are adding the dependency like this:

libraryDependencies ++= Seq(
  ws
)

Moreover, there is no promise that play-ws 2.5 will work with Play 2.7 or even 2.6. Finally, our forums would be a better place to discuss this. Github issues are for reporting bugs and feature requests in Play, not for general discussion and getting help. Given that, I'm closing this.

Best.