Dear Gradle team,
In the following, I describe why we are not using the Gradle Play plugin at our company. The main goal of this post is to serve as a basis of discussion for further improvements to the Gradle Play plugin. Note that we are using Gradle as our main build system for all Java-related projects. For Play projects, however, we currently rely on a brittle integration with SBT.
runPlayBinary is broken
Using SBT, there are two targets to run the Play application in development mode and that support hot-reload:
- “run” which recompiles and reloads the application whenever a new http request is made AND files have changed on the file system.
- “~run” (tilde-run) which recompiles and reloads the application whenever files have changed on the file system.
I use mode 1 far more often, but this is usually a developer preference.
The Gradle continuous mode (–continuous) for Play projects only supports something which resembles the second one. When using SBT, web requests are suspended until the project has been recompiled and reloaded. With Gradle, requests are still operating on the old instance until the switch is made. Why do I prefer the workflow using SBT? I make changes in my IDE and then go to the browser window, press refresh, and (after a short wait) have the guarantee that the new version of my application is loaded. With Gradle, I have to track the command line and check whether the app has already been reloaded.
Weak integration with other plugins
As the Gradle Play plugin is using the new Gradle component model, it is missing all of the integrations with other plugins. It is in particular not based on the existing Java plugin. This means for example that there is no out-of-the box support to generate Eclipse classpath files.
Naming and conventions non-standard
Task names are different to the ones for the Java plugin, for example
- “runPlayBinary” instead of “run”
- “testPlayBinary” instead of “test”
Another weak point is that configurations have been renamed to play, playTest, playRun instead of the usual compile, runtime, testCompile, testRuntime used by the Java plugin. This makes it hard to write generic code in a multi-project setting that is applicable for Play AND standard Java projects. We have lots of configuration code (shared by all projects) that reference the compile or runtime configurations. By introducing Play, we have to introduce an additional layer of indirection which makes this code harder to understand.
No assets pipeline provided out-of-the-box
SBT provides a rich assets pipeline (sbt-web) that integrates nicely with hot-reload. There is (to my knowledge) no equivalent assets pipeline for Gradle. The Gradle documentation states that the Play plugin only “comes with a simplistic asset processing pipeline” as “many organizations have their own custom pipeline for processing assets”. I am rather skeptical about this statement. I agree that many organizations customize their pipeline for processing assets. This does not mean however that the building blocks used in their pipeline are custom-written. Here I miss a few building blocks offered by Gradle core. For example, the Javascript minify task (that wraps the Google Closure compiler) does not support any compiler options (see also JavaScriptMinify has no options ).