Why we are not using the Gradle Play plugin

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 ).

1 Like

Thanks for the feedback. The current Play support in Gradle is intended to be a usable milestone with further functionality to be provided in the future, so although it’s unfortunate that these issues are a blocker for you, your feedback does help us improve upon what’s already there. Some of the things you’ve highlighted (e.g. behavior of runPlayBinary and better support for assets pipeline) are already identified in the play design doc (https://github.com/gradle/gradle/blob/master/design-docs/play-support.md). The details of these stories will improve as we get around to working on these capabilities.

With respect to the naming of tasks and configurations, I understand the frustration, however I’m not sure that we would change these conventions. For instance, the task names reflect the fact that we want to eventually support multiple Play components and/or binaries in a project (right now we only support one component - “play” with one binary “playBinary”). Once we do support multiple variants, we will need tasks that reflect the binary name, which is why they are named this way. From a configuration perspective, the Play plugin was considered something different than the java plugin and could potentially coexist in a project with a java component, so the decision to use different configuration names was deliberate. Having said that, the play configurations are just configurations like any other, so you could potentially create a “compile” configuration, for instance, and have the “play” configuration extend from that. Then you could manage the compile configuration similarly to a java project and the play configuration would pick up those changes. I’m not sure what your requirements are in this regard, and maybe you’ve tried that, I’m just pointing out that there is some degree of flexibility there.

Hi @Gary_Hale, thanks for your reply. I’m trying to create an Eclipse project and make it download all dependencies but somehow it’s not working. This is my build.gralde:

plugins {
    id 'play'
}

apply plugin: 'eclipse'

configurations {
    compile
    testCompile
    play.extendsFrom(compile)
    playTest.extendsFrom(testCompile)
}

repositories {
    jcenter()
    maven {
        name "typesafe-maven-release"
        url "https://repo.typesafe.com/typesafe/maven-releases"
    }
    ivy {
        name "typesafe-ivy-release"
        url "https://repo.typesafe.com/typesafe/ivy-releases"
        layout "ivy"
    }
}

dependencies {
    compile 'commons-lang:commons-lang:2.6'
    testCompile "com.google.guava:guava:17.0"
}

model {
    components {
        play {
            targetPlatform 'play-2.4.0'
        }
    }
}

model {
    components {
        play {
            injectedRoutesGenerator = true
        }
    }
}

I also try to use this with buildship plugin but it don’t download dependencies also. Can you please help?

Thanks. :slight_smile:

Also having issues using both eclipse or Intellij with the plugin. It appears that it does not recognize how to deal with dependencies? This seems like a major limitation that is not documented if this is the case. Anyone get this to work?

Hello,

I was stuck with the same issues as you that is to say not being able to use a play project in a Eclipse IDE environnement. I finally found a way that I described here:
http://stackoverflow.com/questions/35206847/how-to-make-gradle-eclipse-play-framework-work-together/35316044#35316044

Hope it can help.