playframework / twirl

Twirl is Play's default template engine
Apache License 2.0
545 stars 108 forks source link

Gradle Plugin: Documentation of a few gotchas #745

Closed Nezisi closed 4 months ago

Nezisi commented 6 months ago

I migrated a few of our repositories from SBT to Gradle thanks to the new shiny plugins ;)

Our code base in SBT looked like this:

<project name>/app/<java package directories>/templates/ (for example: "example-project/app/org/bla/foobar/client/templates/")

It was based on the Play layout plugin and had the twirl templates mixed up in the "app" source set. All files, except the Twirl Templates, are written in Java.

As we wanted to migrate to a Gradle only approach and get rid of the Play layout (as it is a major source of confusion), I made a tiny mistake that cost me a few hours:

As all files except the Twirl templates were in Java, I converted the source project to a Java sourceset:

<project name>/src/main/java/<java package directories>/templates/ (for example: "example-project/src/main/java/org/bla/foobar/client/templates/")

Which didn't work out at all... The plugin didn't even start. The solution to the puzzle was to convert the project to a proper scala project with the scala plugin and the scala sourceset.

It worked like a charm ;) Would be I think a nice warning for those migrating Java Projects, as it can save a lot of frustration.

Or am I missing something?

The second gotcha was that - despite the twirl templates being small - the Gradle daemon process loved too OOM.

A link to https://docs.gradle.org/current/userguide/scala_plugin.html#sec:scala_compiling_in_external_process and maybe https://docs.gradle.org/current/userguide/build_environment.html ("org.gradle.jvmargs=(JVM arguments)") would be nice.

(for the play framework gradle plugin, too)

ihostage commented 6 months ago

I migrated a few of our repositories from SBT to Gradle thanks to the new shiny plugins ;)

Hi, @Nezisi! 👋 Firstly, thank you a lot that try to use our new Gradle plugin!

As all files except the Twirl templates were in Java, I converted the source project to a Java sourceset:

<project name>/src/main/java/<java package directories>/templates/ (for example: "example-project/src/main/java/org/bla/foobar/client/templates/")

Which didn't work out at all... The plugin didn't even start.

Can you create a small project with state that reproduce your problem before you fixed it? 🤔

The second gotcha was that - despite the twirl templates being small - the Gradle daemon process loved too OOM.

Currently, I think that a OOM problems can be related with https://github.com/playframework/playframework/pull/10939. When we merge this PR and if problem doesn't go out, we will spend a time for detailed analyzing a root cause of new OOM problem.

Nezisi commented 6 months ago

@ihostage Thank you for the Gradle plugins. :)

https://github.com/Nezisi/play-twirl-scala-vs-java-sourceset

I added a README.md where I tried to execute all my commands with gradle --info switch.

ihostage commented 4 months ago

Hi, @Nezisi! 👋 Sorry for the delay.

It was based on the Play layout plugin and had the twirl templates mixed up in the "app" source set.

I'm not sure that it's a classical Play layout when all templates stores in app/views but anyway it's ok 😄

So, about first gotcha that you demonstrated in https://github.com/Nezisi/play-twirl-scala-vs-java-sourceset It isn't a problem of Twirl plugin. I'll explain. As you said

All files, except the Twirl Templates, are written in Java.

and it's ok that you moved their to src/main/java. But, as I see, you understand that Twirl compiles templates to scala sources and you use these classes in your Java code. In this case you need to understand a layout of a Gradle Scala Plugin.

src/main/java — Production Java source. src/main/scala — Production Scala source. May also contain Java source files for joint compilation.

So as you use a Scala classes in Java you need to use a src/main/scala to joint compilation. But you don't have to do that and just configure your source sets in target_project_gradle_java_wrong project (see this for details) by next:

sourceSets {
    main {
        twirl {
            srcDir("src/main/java")
        }
        scala {
            srcDirs("src/main/scala", "src/main/java")
        }
        java {
            setSrcDirs(emptyList<File>())
        }
    }
}

Also, you don't have to apply a Scala plugin manually like in target_project_gradle_scala_right, because Twirl plugin does that implicitly. Just configure your source sets in your pure Java project, nothing more 😉

About the second gotcha, I think it was solved in https://github.com/playframework/twirl/pull/746 😉

mkurz commented 4 months ago

So there is nothing to be changed and we can already cut a new release?

ihostage commented 4 months ago

So there is nothing to be changed and we can already cut a new release?

Yep, Matthias, I think we are ready to cut a new release with fix of OOM problem 😉

Nezisi commented 4 months ago

@ihostage Great summary, thanks alot.

Could we maybe add this to the README.md?

Or even better: Add it to the playframework-gradle plugin and add an link to twirl project README to the playframework-gradle paragraph.

Its not rocket science, I know. But I'd consider it some kind of paper cut bug, as its not so obvious without knowing the internals?

Feel free to close the ticket if you think otherwise.

ihostage commented 4 months ago

Hi, @Nezisi!

Could we maybe add this to the README.md?

Yes, why not. Can you check a #773?