Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kotlin Controllers are not able to resolve Twirl templates #15

Open
adrianpowell opened this issue Jul 12, 2017 · 4 comments
Open

Kotlin Controllers are not able to resolve Twirl templates #15

adrianpowell opened this issue Jul 12, 2017 · 4 comments

Comments

@adrianpowell
Copy link

I started with a very simple Play application which has a Controller in Kotlin that references a Twirl template. The Twirl needs to be complied before the Kotlin so that the generated class is visible, but the Kotlin appears to be compiled first resulting in errors:

[info] Compiling 2 Kotlin sources
[error] /Users/apowell/dev/kotlin-play-poc/app/controllers/HomeController.kt: 6, 19: Unresolved reference: index
[error] /Users/apowell/dev/kotlin-play-poc/app/controllers/HomeController.kt: 11, 27: Unresolved reference: index
[error] Compilation failed. See log for more details
[error] (compile:kotlinCompile) Compilation failed. See log for more details

My Controller is:

package controllers

import play.mvc.Controller
import play.mvc.Result
import play.mvc.Results
import views.html.index

class HomeController : Controller() {

    fun home(): Result {
        return Results.ok(index.apply("Your new application is ready"))
    }
}

If I remove the reference to the Twirl template (eg: return Results.ok("Kotlin controller is working")) then the compilation is successful, Java controllers can reference this template and the application runs.

Is there a way to force the Twirl/scala compilation to happen first?

@pfn
Copy link
Owner

pfn commented Jul 12, 2017

kotlin cannot compile before scala in this plugin. This is due to mix-mode scala+java+kotlin support.

If twirl compiles directly to classes, you can make kotlinCompile depend on twirl:

kotlinCompile in Compile := ((kotlinCompile in Compile) dependsOn theTwirlTaskIDontKnowWhatItIs).value

@adrianpowell
Copy link
Author

I'll see if I can find out the name of that task, thanks for the pointer.

@adrianpowell
Copy link
Author

adrianpowell commented Jul 12, 2017

kotlinCompile in Compile := ((kotlinCompile in Compile) dependsOn (TwirlKeys.compileTemplates in Compile)).value

will compile the Twirl templates, but the task doesn't result in .class files but rather some .scala files under target/scala-1.12/twirl/main/views/html.

Since the Kotlin Controller needs to import and reference these as classes, it sounds like I would need a mix-mode scala+java+kotlin which doesn't exist. Thanks for your help.

@pfn
Copy link
Owner

pfn commented Jul 12, 2017

You will need to remove the dependency on kotlinCompile from compile (see how it's defined in Defaults.scala for sbt and re-declare it); it will look something like the following:

   // fix task scopes as necessary.
   compile in Compile := Defaults.compileTask.value
   compile in Compile := { // this will make kotlinCompile run after compile
      KotlinCompile.compile(kotlincOptions.value,
         sourceDirectories.value, kotlincPluginOptions.value,
         dependencyClasspath.value, (managedClasspath in KotlinInternal).value,
         classDirectory.value, streams.value)
     (compile in Compile).value
   },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants