Play 2.7.0-M1 released!

Hi all,

The Play team is proud to announce the first milestone of Play 2.7.0. Like all milestone releases, the primary goal is to get feedback, so please let us know if something isn’t working or you see something that should be improved. If you are the author of a Play module, we would recommend checking out this release to see how it will affect your module.

See details on our blog here:

Please use this thread to give us feedback about the milestone.

Best.

2 Likes

Things I ran into, might be wrong in my assertions here:

  • play.Configuration is now com.typesafe.config.Config
  • HttpExecution#defaultContext() was removed but Execution#internalContext() was not, even though it is also marked as deprecated since 2.6.
  • Http.RequestHeader#getHeader was removed, replaced by header which returns an Optional<String>
  • play-iteratees doesn’t have a scala 2.13 version yet. Neither does the memcached plugin(which I realize is 3rd party).
  • This item popped up that I don’t have imported anywhere:
|[warn] ||com.typesafe.play:play-omnidoc_2.13.0-M3:2.7.0-M1 ((play.sbt.PlaySettings) PlaySettings.scala#L81)|
|---|---|---|
|[warn] ||  +- project:project_2.13.0-M3:myversion|

I checked everywhere, the term “omnidoc” doesn’t appear anywhere in code nor setup scripts, so I’m assuming it’s something internal?

Checking here: https://mvnrepository.com/artifact/com.typesafe.play/play-omnidoc it seems to be an issue of the scala 2.13 version not existing.

And that last one stopped my progress. At least with scala 2.13. I’ll try 2.12 on a later date.

Also, stepping into source code and downloading sources made Intellij complain about something in EssentialAction#apply(RequestHeader), namely that map(Result::asScala is invalid. State Bad return type in method reference: cannot convert play.api.mvc.Result to B.

B being the B from this definition: map(Function<? super A, ? extends B> var1, Executor var2);

Since Intellij is complaining about it, I thought I’d pass it on.

Hope the migration guide is coming soon, to tell me about all the things I don’t actually know about.

1 Like

I think It’d be helpful to have a 2.7.x branch for the starter template https://github.com/playframework/play-scala-starter-example

Wow, thank you so much for the detailed feedback, @KoenDG. Here are some comments about your points.

First of all, there is a migration guide already:

But it was not published for some reason. I will investigate it and see how to solve the problem.

Yes and I’ve just noticed that is not clearly documented on the migration guide linked above. It would be useful to have it there since play.Configuration was widely used. I appreciate if you or any other member of the community can take a look at the current migration guide and improve it with such “details”.

Most of the Java deprecated APIs where removed here but we need to find time to also remove the Scala deprecated APIs.

I see it was deprecated too, so it was removed at the pull request linked above.

Do you mind opening an issue there so that I can get a notification on this? I will also take a look at other standalone projects to see if they all have Scala 2.13 support. This also includes Omnidoc which is the next point. :slight_smile:

This is all happening here:

Omnidoc is automatically added as a dependency so that you can have /@documentation URL when running Play locally.

I get these errors on IDEA sometimes too. But if sbt does not complain about it, then I consider that it is a problem with IDEA and not my code. :smile:

Again, thanks for your time to try the milestone and give us feedback.

Best.

Hi @naferx,

We will do it too. I’m just unsure if it is worth to do it now or only when we have a release candidate with stable API. What do you think?

Best.

It was a quick thought I had, providing the template so people can start experimenting with the new milestone quickly, but it sounds reasonable to do it when a RC is out.

@marcospereira Issue created on github.

I’ll have a look at the migration guide for missing things when I try the update next time, probably tonight(GMT+1).

1 Like

I’m attempting an upgrade with scala 2.12 now, going to edit this post as I come across things, keeping them here mostly to not forget them.

Not present in the migration doc, removal of this: https://github.com/playframework/playframework/blob/2.6.15/framework/src/play/src/main/java/play/libs/concurrent/HttpExecution.java#L49

EDIT 1: The new Config class doesn’t seem to support default values. Look into what I’m supposed to do there.

What is currently

return configuration.getString(key, defaultValue);

Seems to have to become

        String str = configuration.getString(key);
        if (str == null) {
            return defaultValue;
        } else {
            return str;
        }

Which I don’t really like.

EDIT 2:

The previous issue seems to be present for all getters, which is troublesome in the case of getBoolean. The only correct migration I can think of is first calling hasPath to see if the flag exists in the configuration.

Ok, in scala 2.12 I got this one project to compile, but it won’t run, produces this stacktrace:

! @78dd9o295 - Internal server error, for (GET) [/] →

play.api.UnexpectedException: Unexpected exception[NoClassDefFoundError: play/api/cache/CacheApi]
at play.core.server.DevServerStart$$anon$1.reload(DevServerStart.scala:189)
at play.core.server.DevServerStart$$anon$1.get(DevServerStart.scala:124)
at play.core.server.netty.PlayRequestHandler.handle(PlayRequestHandler.scala:84)
at play.core.server.netty.PlayRequestHandler.channelRead(PlayRequestHandler.scala:177)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at com.typesafe.netty.http.HttpStreamsHandler.channelRead(HttpStreamsHandler.java:129)
at com.typesafe.netty.http.HttpStreamsServerHandler.channelRead(HttpStreamsServerHandler.java:96)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:647)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:582)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:499)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:461)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NoClassDefFoundError: play/api/cache/CacheApi
at com.github.mumoshu.play2.memcached.MemcachedModule$$anonfun$$lessinit$greater$1.apply(MemcachedModule.scala:61)
at com.github.mumoshu.play2.memcached.MemcachedModule$$anonfun$$lessinit$greater$1.apply(MemcachedModule.scala:20)
at play.api.inject.SimpleModule.bindings(Module.scala:88)
at play.api.inject.guice.GuiceableModuleConversions.guice(GuiceInjectorBuilder.scala:340)
at play.api.inject.guice.GuiceableModuleConversions.guice$(GuiceInjectorBuilder.scala:339)
at play.api.inject.guice.GuiceableModule$.guice(GuiceInjectorBuilder.scala:274)
at play.api.inject.guice.GuiceableModuleConversions$$anon$3.$anonfun$guiced$2(GuiceInjectorBuilder.scala:319)
at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
at scala.collection.immutable.List.foreach(List.scala:389)
at scala.collection.TraversableLike.map(TraversableLike.scala:234)
at scala.collection.TraversableLike.map$(TraversableLike.scala:227)
at scala.collection.immutable.List.map(List.scala:295)
at play.api.inject.guice.GuiceableModuleConversions$$anon$3.guiced(GuiceInjectorBuilder.scala:319)
at play.api.inject.guice.GuiceableModule$.$anonfun$guiced$1(GuiceInjectorBuilder.scala:296)
at scala.collection.TraversableLike.$anonfun$flatMap$1(TraversableLike.scala:241)
at scala.collection.immutable.List.foreach(List.scala:389)
at scala.collection.TraversableLike.flatMap(TraversableLike.scala:241)
at scala.collection.TraversableLike.flatMap$(TraversableLike.scala:238)
at scala.collection.immutable.List.flatMap(List.scala:352)
at play.api.inject.guice.GuiceableModule$.guiced(GuiceInjectorBuilder.scala:296)
at play.api.inject.guice.GuiceBuilder.createModule(GuiceInjectorBuilder.scala:171)
at play.api.inject.guice.GuiceApplicationBuilder.applicationModule(GuiceApplicationBuilder.scala:111)
at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:186)
at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:139)
at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
at play.core.server.DevServerStart$$anon$1.$anonfun$reload$3(DevServerStart.scala:173)
at play.utils.Threads$.withContextClassLoader(Threads.scala:22)
at play.core.server.DevServerStart$$anon$1.reload(DevServerStart.scala:165)
… 35 common frames omitted
Caused by: java.lang.ClassNotFoundException: play.api.cache.CacheApi
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
… 63 common frames omitted
Stopping Play…

All settings related to cache and the wrapper class I use are unchanged. Not a letter of code touched. Works fine in 2.6.15

Using net.spy spymemcached 2.12.3 and com.github.mumoshu play2-memcached-play26 0.9.0.

Also, the project is in Java, so I’m not using play.api.cache.CacheApi, I’m using play.cache.SyncCacheApi.

I’m gonna stop for tonight, in the next few days I’ll try and clone an example starter project on github and try to mimick this behavior.

your memcached dependency is not compatible with 2.7

1 Like

I am happy to report, things seem to be running fine with my application, will need to perform more in-depth tests, but so far so good. Application starts up and runs fine (locally) and passes all existing test cases. My app is built with Play 2.6, and all I had to do is:

  • update the Play version to 2.7.0-M1
  • add the missing apache commons libs as outlined in the migration doc
1 Like

Thank you for reporting that, @chrono_b. Glad to hear that everything is going well.

Best.

This just popped into my head: https://github.com/playframework/playframework/pull/8011

Didn’t see it in the migration document on master. That should probably get a mention. Really useful for projects that act as a REST api with no actual frontend.

Hi @KoenDG,

PlayService is already part of Play 2.6:

https://www.playframework.com/documentation/2.6.x/Highlights26#PlayService-sbt-plugin-(experimental)

For 2.7 we should just remove the “experimental” flag.

Best.

I never noticed that. But indeed, this PR is linked at the bottom of the one I linked: https://github.com/playframework/playframework/pull/8035

Which merges it into 2.6.x

My bad.